ruby-on-rails - 为什么 ActiveRecord 对每个连接发出单独的查询?

标签 ruby-on-rails ruby database performance activerecord

我正在执行 ActiveRecord 查找操作(通过“will_paginate”库),如下所示:

  contacts = Contact.paginate(:all,
    :conditions => conditions_specified,
    :select => "DISTINCT contacts.*",
    :joins => joins,
    :include => [:addresses, :emails, :phone_numbers, {:addresses => :organization}],
    :page => page,
    :per_page => @@PAGE_SIZE,
    :order => 'last_name, first_name, middle_name')

在控制台中,我得到如下所示的输出。通过设置 include 参数,我预计这只会产生一个查询。但在输出中我看到很多查询。例如,我很惊讶地看到这一行...

  Address Load (2.5ms)   SELECT `addresses`.* FROM `addresses` WHERE (`addresses`.contact_id IN (94,106,104,108,121,55,40,75,62,4,67,36,77,64,7,35,24,68,57,117,8,30,85))

在下面的输出中。 (我知道 SHOW FIELDS FROM 查询在生产中缓存,因此这不是问题。这都是我试图弄清楚的额外选择。)

Processing ContactController#index (for 127.0.0.1 at 2009-01-03 21:21:18) [GET]
  Session ID: d453897c2f67c29c9a68d3fbc7b94f7b
  ContactSearch Columns (4.4ms)   SHOW FIELDS FROM `contact_searches`
  Contact Load (1.1ms)   SELECT DISTINCT contacts.* FROM `contacts` WHERE (contacts.last_name LIKE '%n%') ORDER BY last_name, first_name, middle_name LIMIT 0, 35
  Contact Columns (2.3ms)   SHOW FIELDS FROM `contacts`
  Address Load (2.5ms)   SELECT `addresses`.* FROM `addresses` WHERE (`addresses`.contact_id IN (94,106,104,108,121,55,40,75,62,4,67,36,77,64,7,35,24,68,57,117,8,30,85))
  Address Columns (2.7ms)   SHOW FIELDS FROM `addresses`
  Email Load (1.7ms)   SELECT `emails`.* FROM `emails` WHERE (`emails`.contact_id IN (94,106,104,108,121,55,40,75,62,4,67,36,77,64,7,35,24,68,57,117,8,30,85))
  Email Columns (1.8ms)   SHOW FIELDS FROM `emails`
  PhoneNumber Load (3.3ms)   SELECT `phone_numbers`.* FROM `phone_numbers` WHERE (`phone_numbers`.contact_id IN (94,106,104,108,121,55,40,75,62,4,67,36,77,64,7,35,24,68,57,117,8,30,85))
  PhoneNumber Columns (3.0ms)   SHOW FIELDS FROM `phone_numbers`
  Organization Columns (2.9ms)   SHOW FIELDS FROM `organizations`
  Organization Load (0.9ms)   SELECT * FROM `organizations` WHERE (`organizations`.`id` IN (99,116,44,6,23,78,107,91,79,119,14,120,71,26,59,94,27,100,62,1,51,29,30,2,65,76,5))
Rendering template within layouts/main
Rendering contact/index
Rendered contact/_field_function_specifier (0.9ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_field_function_specifier (0.6ms)
Rendered contact/_search_form (14.1ms)
Rendered contact/_quick_view_contact_info (3.2ms)
Rendered contact/_quick_view_contact_info (2.1ms)
Rendered contact/_quick_view_contact_info (1.9ms)
Rendered contact/_quick_view_contact_info (1.9ms)
Rendered contact/_quick_view_contact_info (0.8ms)
Rendered contact/_quick_view_contact_info (2.0ms)
Rendered contact/_quick_view_contact_info (2.4ms)
Rendered contact/_quick_view_contact_info (1.7ms)
Rendered contact/_quick_view_contact_info (1.4ms)
Rendered contact/_quick_view_contact_info (1.7ms)
Rendered contact/_quick_view_contact_info (2.2ms)
Rendered contact/_quick_view_contact_info (1.5ms)
Rendered contact/_quick_view_contact_info (2.0ms)
Rendered contact/_quick_view_contact_info (1.7ms)
Rendered contact/_quick_view_contact_info (1.8ms)
Rendered contact/_quick_view_contact_info (3.6ms)
Rendered contact/_quick_view_contact_info (2.2ms)
Rendered contact/_quick_view_contact_info (2.2ms)
Rendered contact/_quick_view_contact_info (1.9ms)
Rendered contact/_quick_view_contact_info (1.7ms)
Rendered contact/_quick_view_contact_info (2.0ms)
Rendered contact/_quick_view_contact_info (2.1ms)
Rendered contact/_quick_view_contact_info (1.9ms)
Completed in 308ms (View: 104, DB: 27) | 200 OK [http://localhost/contact]

最佳答案

我做了更多研究并找到了答案。我正在为以后搜索的人更新此内容。长答案在 this blog post .

看来,当您执行同时具有连接和限制的查找时,ActiveRecord 必须首先查询主表以获取要返回的行的 ID,然后仅使用 ID 重做查询以应用限制。

由于我使用的是 will_paginate,所以发生的情况是 will_paginate 使用限制查询来进行分页。

关于ruby-on-rails - 为什么 ActiveRecord 对每个连接发出单独的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/410512/

相关文章:

ruby-on-rails - Rails 引擎中的 Ember CLI 应用程序

ruby-on-rails - 随机范围,但可以重复 n 次

ruby-on-rails - 使用 PayPal gem 进行点对点支付

ruby - 升级到 ruby​​ 2.2.0 后的警告

ruby - 是否可以使这个 ruby​​ 正则表达式代码更短?

mysql - 如何将默认数据插入到依赖于另一列的列中?

ruby-on-rails - 模型 bool 方法无法正常工作

ruby-on-rails - Encoding::UndefinedConversionError ("\xE2"从 ASCII-8BIT 到 UTF-8):基于 ROR + MongoDB 的应用程序中的错误

sql - 如何从 T-SQL 中的表中选择前 N 行?

php - 如何使用具有日期条件的其他表减去整数数据?