Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Improve performance on :include/:conditions/:limit queries by selecti…

…vely joining in the pre-query. Closes #9560 [dasil003]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8977 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 4ca170fcea17ca0cd52677c39e865a0934ecd7d3 1 parent 51b6619
@NZKoz NZKoz authored
View
2  activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Improve performance on :include/:conditions/:limit queries by selectively joining in the pre-query. #9560 [dasil003]
+
* Perf fix: Avoid the use of named block arguments. Closes #11109 [adymo]
* PostgreSQL: support server versions 7.4 through 8.0 and the ruby-pg driver. #11127 [jdavis]
View
37 activerecord/lib/active_record/associations.rb
@@ -1388,7 +1388,13 @@ def select_limited_ids_list(options, join_dependency)
def construct_finder_sql_for_association_limiting(options, join_dependency)
scope = scope(:find)
- is_distinct = !options[:joins].blank? || include_eager_conditions?(options) || include_eager_order?(options)
+
+ # Only join tables referenced in order or conditions since this is particularly slow on the pre-query.
+ tables_from_conditions = conditions_tables(options)
+ tables_from_order = order_tables(options)
+ all_tables = tables_from_conditions + tables_from_order
+
+ is_distinct = !options[:joins].blank? || include_eager_conditions?(options, tables_from_conditions) || include_eager_order?(options, tables_from_order)
sql = "SELECT "
if is_distinct
sql << connection.distinct("#{connection.quote_table_name table_name}.#{primary_key}", options[:order])
@@ -1398,7 +1404,7 @@ def construct_finder_sql_for_association_limiting(options, join_dependency)
sql << " FROM #{connection.quote_table_name table_name} "
if is_distinct
- sql << join_dependency.join_associations.collect(&:association_join).join
+ sql << join_dependency.join_associations.reject{ |ja| !all_tables.include?(ja.table_name) }.collect(&:association_join).join
add_joins!(sql, options, scope)
end
@@ -1416,8 +1422,7 @@ def construct_finder_sql_for_association_limiting(options, join_dependency)
return sanitize_sql(sql)
end
- # Checks if the conditions reference a table other than the current model table
- def include_eager_conditions?(options)
+ def conditions_tables(options)
# look in both sets of conditions
conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond|
case cond
@@ -1426,17 +1431,29 @@ def include_eager_conditions?(options)
else all << cond
end
end
- return false unless conditions.any?
- conditions.join(' ').scan(/([\.\w]+).?\./).flatten.any? do |condition_table_name|
+ conditions.join(' ').scan(/([\.\w]+).?\./).flatten
+ end
+
+ def order_tables(options)
+ order = options[:order]
+ return [] unless order && order.is_a?(String)
+ order.scan(/([\.\w]+).?\./).flatten
+ end
+
+ # Checks if the conditions reference a table other than the current model table
+ def include_eager_conditions?(options,tables = nil)
+ tables = conditions_tables(options)
+ return false unless tables.any?
+ tables.any? do |condition_table_name|
condition_table_name != table_name
end
end
# Checks if the query order references a table other than the current model's table.
- def include_eager_order?(options)
- order = options[:order]
- return false unless order
- order.to_s.scan(/([\.\w]+).?\./).flatten.any? do |order_table_name|
+ def include_eager_order?(options,tables = nil)
+ tables = order_tables(options)
+ return false unless tables.any?
+ tables.any? do |order_table_name|
order_table_name != table_name
end
end

0 comments on commit 4ca170f

Please sign in to comment.
Something went wrong with that request. Please try again.