Changeset 8977
- Timestamp:
- 03/03/08 06:23:38 (1 year ago)
- Files:
-
- trunk/activerecord/CHANGELOG (modified) (1 diff)
- trunk/activerecord/lib/active_record/associations.rb (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activerecord/CHANGELOG
r8957 r8977 1 1 *SVN* 2 3 * Improve performance on :include/:conditions/:limit queries by selectively joining in the pre-query. #9560 [dasil003] 2 4 3 5 * Perf fix: Avoid the use of named block arguments. Closes #11109 [adymo] trunk/activerecord/lib/active_record/associations.rb
r8942 r8977 1389 1389 def construct_finder_sql_for_association_limiting(options, join_dependency) 1390 1390 scope = scope(:find) 1391 is_distinct = !options[:joins].blank? || include_eager_conditions?(options) || include_eager_order?(options) 1391 1392 # Only join tables referenced in order or conditions since this is particularly slow on the pre-query. 1393 tables_from_conditions = conditions_tables(options) 1394 tables_from_order = order_tables(options) 1395 all_tables = tables_from_conditions + tables_from_order 1396 1397 is_distinct = !options[:joins].blank? || include_eager_conditions?(options, tables_from_conditions) || include_eager_order?(options, tables_from_order) 1392 1398 sql = "SELECT " 1393 1399 if is_distinct … … 1399 1405 1400 1406 if is_distinct 1401 sql << join_dependency.join_associations. collect(&:association_join).join1407 sql << join_dependency.join_associations.reject{ |ja| !all_tables.include?(ja.table_name) }.collect(&:association_join).join 1402 1408 add_joins!(sql, options, scope) 1403 1409 end … … 1417 1423 end 1418 1424 1419 # Checks if the conditions reference a table other than the current model table 1420 def include_eager_conditions?(options) 1425 def conditions_tables(options) 1421 1426 # look in both sets of conditions 1422 1427 conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond| … … 1427 1432 end 1428 1433 end 1429 return false unless conditions.any? 1430 conditions.join(' ').scan(/([\.\w]+).?\./).flatten.any? do |condition_table_name| 1434 conditions.join(' ').scan(/([\.\w]+).?\./).flatten 1435 end 1436 1437 def order_tables(options) 1438 order = options[:order] 1439 return [] unless order && order.is_a?(String) 1440 order.scan(/([\.\w]+).?\./).flatten 1441 end 1442 1443 # Checks if the conditions reference a table other than the current model table 1444 def include_eager_conditions?(options,tables = nil) 1445 tables = conditions_tables(options) 1446 return false unless tables.any? 1447 tables.any? do |condition_table_name| 1431 1448 condition_table_name != table_name 1432 1449 end … … 1434 1451 1435 1452 # Checks if the query order references a table other than the current model's table. 1436 def include_eager_order?(options )1437 order = options[:order]1438 return false unless order1439 order.to_s.scan(/([\.\w]+).?\./).flatten.any? do |order_table_name|1453 def include_eager_order?(options,tables = nil) 1454 tables = order_tables(options) 1455 return false unless tables.any? 1456 tables.any? do |order_table_name| 1440 1457 order_table_name != table_name 1441 1458 end