From: Jorgen Loland Date: May 18 2011 10:37am Subject: bzr commit into mysql-trunk branch (jorgen.loland:3307) Bug#12551047 List-Archive: http://lists.mysql.com/commits/137637 X-Bug: 12551047 Message-Id: <20110518103709.9E3BDB54@atum21.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============7573259012770236934==" --===============7573259012770236934== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/jl208045/mysql/wl4800/mysql-next-mr-opt-backporting-wl4800-12551047/ based on revid:guilhem.bichot@stripped 3307 Jorgen Loland 2011-05-18 Bug#12551047: ASSERTION NO_ASSERT_ON_SYNTAX_ERROR FAILED IN OPT_TRACE_STMT::SYNTAX_ERROR Optimizer tracing: get_best_covering_ror_intersect() was not tested by any existing mtr test case so we had no test case to use with optimizer tracing either. John found a case when doing RQG testing, so now tracing could be fixed and a few test cases added to optimizer_trace_range*.test @ sql/opt_range.cc Fix optimizer tracing in previously untested function get_best_covering_ror_intersect() modified: mysql-test/include/optimizer_trace_range.inc mysql-test/r/optimizer_trace_range_no_prot.result mysql-test/r/optimizer_trace_range_ps_prot.result sql/opt_range.cc === modified file 'mysql-test/include/optimizer_trace_range.inc' --- a/mysql-test/include/optimizer_trace_range.inc 2011-04-06 09:19:23 +0000 +++ b/mysql-test/include/optimizer_trace_range.inc 2011-05-18 10:37:05 +0000 @@ -253,3 +253,36 @@ SELECT * FROM information_schema.OPTIMIZ --echo DROP TABLE t1; + +# Analyze whether to use covering roworder intersect +CREATE TABLE t1 ( + pk INT PRIMARY KEY, + i1 INT, + i2 INT, + v varchar(1), + INDEX i1_idx (i1), + INDEX v_idx (v,i1) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1, 1, 9,'a'), (2, 2, 8,'b'), (3, 3, 7,'c'), + (4, 4, 6,'d'), (5, 5, 5,'e'); + +--echo +--echo # Covering ROR intersect not chosen: only one scan used +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3; +--echo +SELECT * FROM information_schema.OPTIMIZER_TRACE; + +DROP INDEX i1_idx ON t1; +CREATE INDEX i1_i2_idx ON t1 (i2,i1); + +--echo +--echo # Covering ROR intersect not chosen: cost +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND i2 = 1 AND v = 'a' AND pk < 3; +--echo +SELECT * FROM information_schema.OPTIMIZER_TRACE; + +# Todo: make a test case that chooses ROR intersect + +--echo +DROP TABLE t1; === modified file 'mysql-test/r/optimizer_trace_range_no_prot.result' --- a/mysql-test/r/optimizer_trace_range_no_prot.result 2011-05-06 12:58:06 +0000 +++ b/mysql-test/r/optimizer_trace_range_no_prot.result 2011-05-18 10:37:05 +0000 @@ -4920,3 +4920,523 @@ EXPLAIN SELECT DISTINCT i1 FROM t1 WHERE } 0 0 DROP TABLE t1; +CREATE TABLE t1 ( +pk INT PRIMARY KEY, +i1 INT, +i2 INT, +v varchar(1), +INDEX i1_idx (i1), +INDEX v_idx (v,i1) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 1, 9,'a'), (2, 2, 8,'b'), (3, 3, 7,'c'), +(4, 4, 6,'d'), (5, 5, 5,'e'); + +# Covering ROR intersect not chosen: only one scan used +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY,i1_idx,v_idx i1_idx 5 const 1 Using index condition; Using where + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3 { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "expanded_query": "/* select#1 */ select `test`.`t1`.`v` AS `v` from `test`.`t1` where ((`test`.`t1`.`i1` = 1) and (`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "((`test`.`t1`.`i1` = 1) and (`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal('a', `test`.`t1`.`v`))" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal('a', `test`.`t1`.`v`))" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal('a', `test`.`t1`.`v`))" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "ref_optimizer_key_uses": [ + { + "database": "test", + "table": "t1", + "field": "i1", + "equals": "1", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "v", + "equals": "'a'", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "i1", + "equals": "1", + "null_rejecting": false + } + ] /* ref_optimizer_key_uses */ + }, + { + "records_estimation": [ + { + "database": "test", + "table": "t1", + "range_analysis": { + "table_scan": { + "records": 5, + "cost": 4.1 + } /* table_scan */, + "potential_range_indices": [ + { + "index": "PRIMARY", + "usable": true, + "key_parts": [ + "pk" + ] /* key_parts */ + }, + { + "index": "i1_idx", + "usable": true, + "key_parts": [ + "i1" + ] /* key_parts */ + }, + { + "index": "v_idx", + "usable": true, + "key_parts": [ + "v", + "i1" + ] /* key_parts */ + } + ] /* potential_range_indices */, + "best_covering_index_scan": { + "index": "v_idx", + "cost": 2.0063, + "chosen": true + } /* best_covering_index_scan */, + "setup_range_conditions": [ + ] /* setup_range_conditions */, + "group_index_range": { + "chosen": false, + "cause": "not_group_by_or_distinct" + } /* group_index_range */, + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "PRIMARY", + "ranges": [ + "pk < 3" + ] /* ranges */, + "index_only": false, + "records": 2, + "cost": 2.41, + "rowid_ordered": true, + "chosen": false, + "cause": "cost" + }, + { + "index": "i1_idx", + "ranges": [ + "1 <= i1 <= 1" + ] /* ranges */, + "index_only": false, + "records": 1, + "cost": 2.21, + "rowid_ordered": true, + "chosen": false, + "cause": "cost" + }, + { + "index": "v_idx", + "ranges": [ + "a <= v <= a AND 1 <= i1 <= 1" + ] /* ranges */, + "index_only": true, + "records": 1, + "cost": 2.21, + "rowid_ordered": true, + "chosen": false, + "cause": "cost" + } + ] /* range_scan_alternatives */, + "analyzing_roworder_intersect": { + "intersecting_indices": [ + { + "index": "i1_idx", + "usable": true, + "matching_records_now": 1, + "cumulated_cost": 2, + "isect_covering_with_this_index": false + }, + { + "index": "v_idx", + "usable": true, + "matching_records_now": 0.2, + "cumulated_cost": 2, + "isect_covering_with_this_index": true + } + ] /* intersecting_indices */, + "clustered_pk": { + "clustered_pk_scan_added_to_intersect": true, + "cumulated_cost": 1.1 + } /* clustered_pk */, + "records": 1, + "cost": 1.1, + "covering": false, + "chosen": true + } /* analyzing_roworder_intersect */, + "make_covering_roworder_intersect": { + "included_indices": [ + "v_idx" + ] /* included_indices */, + "covering": true, + "not_included_indices": [ + "i1_idx" + ] /* not_included_indices */, + "chosen": false, + "cause": "only_one_index" + } /* make_covering_roworder_intersect */ + } /* analyzing_range_alternatives */, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "index_roworder_intersect", + "records": 1, + "cost": 1.1, + "covering": false, + "clustered_pk_scan": true, + "intersect_of": [ + { + "type": "range_scan", + "index": "i1_idx", + "records": 1, + "ranges": [ + "1 <= i1 <= 1" + ] /* ranges */ + } + ] /* intersect_of */ + } /* range_access_plan */, + "records_for_plan": 1, + "cost_for_plan": 1.1, + "chosen": true + } /* chosen_range_access_summary */ + } /* range_analysis */ + } + ] /* records_estimation */ + }, + { + "considered_execution_plans": "..." + }, + { + "attaching_conditions_to_tables": { + "original_condition": "((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`i1` = 1) and (`test`.`t1`.`pk` < 3))", + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "database": "test", + "table": "t1", + "attached": "((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))" + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "refine_plan": [ + { + "database": "test", + "table": "t1" + } + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 +DROP INDEX i1_idx ON t1; +CREATE INDEX i1_i2_idx ON t1 (i2,i1); + +# Covering ROR intersect not chosen: cost +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND i2 = 1 AND v = 'a' AND pk < 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY,v_idx,i1_i2_idx v_idx 9 const,const 1 Using index condition; Using where + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND i2 = 1 AND v = 'a' AND pk < 3 { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "expanded_query": "/* select#1 */ select `test`.`t1`.`v` AS `v` from `test`.`t1` where ((`test`.`t1`.`i1` = 1) and (`test`.`t1`.`i2` = 1) and (`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "((`test`.`t1`.`i1` = 1) and (`test`.`t1`.`i2` = 1) and (`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal(1, `test`.`t1`.`i2`) and multiple equal('a', `test`.`t1`.`v`))" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal(1, `test`.`t1`.`i2`) and multiple equal('a', `test`.`t1`.`v`))" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal(1, `test`.`t1`.`i2`) and multiple equal('a', `test`.`t1`.`v`))" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "ref_optimizer_key_uses": [ + { + "database": "test", + "table": "t1", + "field": "v", + "equals": "'a'", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "i1", + "equals": "1", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "i2", + "equals": "1", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "i1", + "equals": "1", + "null_rejecting": false + } + ] /* ref_optimizer_key_uses */ + }, + { + "records_estimation": [ + { + "database": "test", + "table": "t1", + "range_analysis": { + "table_scan": { + "records": 5, + "cost": 4.1 + } /* table_scan */, + "potential_range_indices": [ + { + "index": "PRIMARY", + "usable": true, + "key_parts": [ + "pk" + ] /* key_parts */ + }, + { + "index": "v_idx", + "usable": true, + "key_parts": [ + "v", + "i1" + ] /* key_parts */ + }, + { + "index": "i1_i2_idx", + "usable": true, + "key_parts": [ + "i2", + "i1" + ] /* key_parts */ + } + ] /* potential_range_indices */, + "setup_range_conditions": [ + ] /* setup_range_conditions */, + "group_index_range": { + "chosen": false, + "cause": "not_group_by_or_distinct" + } /* group_index_range */, + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "PRIMARY", + "ranges": [ + "pk < 3" + ] /* ranges */, + "index_only": false, + "records": 2, + "cost": 2.41, + "rowid_ordered": true, + "chosen": true + }, + { + "index": "v_idx", + "ranges": [ + "a <= v <= a AND 1 <= i1 <= 1" + ] /* ranges */, + "index_only": false, + "records": 1, + "cost": 2.21, + "rowid_ordered": true, + "chosen": true + }, + { + "index": "i1_i2_idx", + "ranges": [ + "1 <= i2 <= 1 AND 1 <= i1 <= 1" + ] /* ranges */, + "index_only": false, + "records": 1, + "cost": 2.21, + "rowid_ordered": true, + "chosen": false, + "cause": "cost" + } + ] /* range_scan_alternatives */, + "analyzing_roworder_intersect": { + "intersecting_indices": [ + { + "index": "v_idx", + "usable": true, + "matching_records_now": 1, + "cumulated_cost": 2, + "isect_covering_with_this_index": false + }, + { + "index": "i1_i2_idx", + "usable": true, + "matching_records_now": 0.2, + "cumulated_cost": 2, + "isect_covering_with_this_index": true + } + ] /* intersecting_indices */, + "clustered_pk": { + "clustered_pk_scan_added_to_intersect": true, + "cumulated_cost": 1.1 + } /* clustered_pk */, + "records": 1, + "cost": 1.1, + "covering": false, + "chosen": true + } /* analyzing_roworder_intersect */, + "make_covering_roworder_intersect": { + "included_indices": [ + "v_idx", + "i1_i2_idx" + ] /* included_indices */, + "chosen": false, + "cause": "cost" + } /* make_covering_roworder_intersect */ + } /* analyzing_range_alternatives */, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "index_roworder_intersect", + "records": 1, + "cost": 1.1, + "covering": false, + "clustered_pk_scan": true, + "intersect_of": [ + { + "type": "range_scan", + "index": "v_idx", + "records": 1, + "ranges": [ + "a <= v <= a AND 1 <= i1 <= 1" + ] /* ranges */ + } + ] /* intersect_of */ + } /* range_access_plan */, + "records_for_plan": 1, + "cost_for_plan": 1.1, + "chosen": true + } /* chosen_range_access_summary */ + } /* range_analysis */ + } + ] /* records_estimation */ + }, + { + "considered_execution_plans": "..." + }, + { + "attaching_conditions_to_tables": { + "original_condition": "((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`i2` = 1) and (`test`.`t1`.`i1` = 1) and (`test`.`t1`.`pk` < 3))", + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "database": "test", + "table": "t1", + "attached": "((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`i2` = 1) and (`test`.`t1`.`pk` < 3))" + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "refine_plan": [ + { + "database": "test", + "table": "t1" + } + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 + +DROP TABLE t1; === modified file 'mysql-test/r/optimizer_trace_range_ps_prot.result' --- a/mysql-test/r/optimizer_trace_range_ps_prot.result 2011-05-06 12:58:06 +0000 +++ b/mysql-test/r/optimizer_trace_range_ps_prot.result 2011-05-18 10:37:05 +0000 @@ -4912,3 +4912,523 @@ EXPLAIN SELECT DISTINCT i1 FROM t1 WHERE } 0 0 DROP TABLE t1; +CREATE TABLE t1 ( +pk INT PRIMARY KEY, +i1 INT, +i2 INT, +v varchar(1), +INDEX i1_idx (i1), +INDEX v_idx (v,i1) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 1, 9,'a'), (2, 2, 8,'b'), (3, 3, 7,'c'), +(4, 4, 6,'d'), (5, 5, 5,'e'); + +# Covering ROR intersect not chosen: only one scan used +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY,i1_idx,v_idx i1_idx 5 const 1 Using index condition; Using where + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3 { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "expanded_query": "/* select#1 */ select `test`.`t1`.`v` AS `v` from `test`.`t1` where ((`test`.`t1`.`i1` = 1) and (`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "((`test`.`t1`.`i1` = 1) and (`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal('a', `test`.`t1`.`v`))" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal('a', `test`.`t1`.`v`))" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal('a', `test`.`t1`.`v`))" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "ref_optimizer_key_uses": [ + { + "database": "test", + "table": "t1", + "field": "i1", + "equals": "1", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "v", + "equals": "'a'", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "i1", + "equals": "1", + "null_rejecting": false + } + ] /* ref_optimizer_key_uses */ + }, + { + "records_estimation": [ + { + "database": "test", + "table": "t1", + "range_analysis": { + "table_scan": { + "records": 5, + "cost": 4.1 + } /* table_scan */, + "potential_range_indices": [ + { + "index": "PRIMARY", + "usable": true, + "key_parts": [ + "pk" + ] /* key_parts */ + }, + { + "index": "i1_idx", + "usable": true, + "key_parts": [ + "i1" + ] /* key_parts */ + }, + { + "index": "v_idx", + "usable": true, + "key_parts": [ + "v", + "i1" + ] /* key_parts */ + } + ] /* potential_range_indices */, + "best_covering_index_scan": { + "index": "v_idx", + "cost": 2.0063, + "chosen": true + } /* best_covering_index_scan */, + "setup_range_conditions": [ + ] /* setup_range_conditions */, + "group_index_range": { + "chosen": false, + "cause": "not_group_by_or_distinct" + } /* group_index_range */, + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "PRIMARY", + "ranges": [ + "pk < 3" + ] /* ranges */, + "index_only": false, + "records": 2, + "cost": 2.41, + "rowid_ordered": true, + "chosen": false, + "cause": "cost" + }, + { + "index": "i1_idx", + "ranges": [ + "1 <= i1 <= 1" + ] /* ranges */, + "index_only": false, + "records": 1, + "cost": 2.21, + "rowid_ordered": true, + "chosen": false, + "cause": "cost" + }, + { + "index": "v_idx", + "ranges": [ + "a <= v <= a AND 1 <= i1 <= 1" + ] /* ranges */, + "index_only": true, + "records": 1, + "cost": 2.21, + "rowid_ordered": true, + "chosen": false, + "cause": "cost" + } + ] /* range_scan_alternatives */, + "analyzing_roworder_intersect": { + "intersecting_indices": [ + { + "index": "i1_idx", + "usable": true, + "matching_records_now": 1, + "cumulated_cost": 2, + "isect_covering_with_this_index": false + }, + { + "index": "v_idx", + "usable": true, + "matching_records_now": 0.2, + "cumulated_cost": 2, + "isect_covering_with_this_index": true + } + ] /* intersecting_indices */, + "clustered_pk": { + "clustered_pk_scan_added_to_intersect": true, + "cumulated_cost": 1.1 + } /* clustered_pk */, + "records": 1, + "cost": 1.1, + "covering": false, + "chosen": true + } /* analyzing_roworder_intersect */, + "make_covering_roworder_intersect": { + "included_indices": [ + "v_idx" + ] /* included_indices */, + "covering": true, + "not_included_indices": [ + "i1_idx" + ] /* not_included_indices */, + "chosen": false, + "cause": "only_one_index" + } /* make_covering_roworder_intersect */ + } /* analyzing_range_alternatives */, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "index_roworder_intersect", + "records": 1, + "cost": 1.1, + "covering": false, + "clustered_pk_scan": true, + "intersect_of": [ + { + "type": "range_scan", + "index": "i1_idx", + "records": 1, + "ranges": [ + "1 <= i1 <= 1" + ] /* ranges */ + } + ] /* intersect_of */ + } /* range_access_plan */, + "records_for_plan": 1, + "cost_for_plan": 1.1, + "chosen": true + } /* chosen_range_access_summary */ + } /* range_analysis */ + } + ] /* records_estimation */ + }, + { + "considered_execution_plans": "..." + }, + { + "attaching_conditions_to_tables": { + "original_condition": "((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`i1` = 1) and (`test`.`t1`.`pk` < 3))", + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "database": "test", + "table": "t1", + "attached": "((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))" + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "refine_plan": [ + { + "database": "test", + "table": "t1" + } + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 +DROP INDEX i1_idx ON t1; +CREATE INDEX i1_i2_idx ON t1 (i2,i1); + +# Covering ROR intersect not chosen: cost +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND i2 = 1 AND v = 'a' AND pk < 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY,v_idx,i1_i2_idx v_idx 9 const,const 1 Using index condition; Using where + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND i2 = 1 AND v = 'a' AND pk < 3 { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "expanded_query": "/* select#1 */ select `test`.`t1`.`v` AS `v` from `test`.`t1` where ((`test`.`t1`.`i1` = 1) and (`test`.`t1`.`i2` = 1) and (`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "((`test`.`t1`.`i1` = 1) and (`test`.`t1`.`i2` = 1) and (`test`.`t1`.`v` = 'a') and (`test`.`t1`.`pk` < 3))", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal(1, `test`.`t1`.`i2`) and multiple equal('a', `test`.`t1`.`v`))" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal(1, `test`.`t1`.`i2`) and multiple equal('a', `test`.`t1`.`v`))" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "((`test`.`t1`.`pk` < 3) and multiple equal(1, `test`.`t1`.`i1`) and multiple equal(1, `test`.`t1`.`i2`) and multiple equal('a', `test`.`t1`.`v`))" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "ref_optimizer_key_uses": [ + { + "database": "test", + "table": "t1", + "field": "v", + "equals": "'a'", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "i1", + "equals": "1", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "i2", + "equals": "1", + "null_rejecting": false + }, + { + "database": "test", + "table": "t1", + "field": "i1", + "equals": "1", + "null_rejecting": false + } + ] /* ref_optimizer_key_uses */ + }, + { + "records_estimation": [ + { + "database": "test", + "table": "t1", + "range_analysis": { + "table_scan": { + "records": 5, + "cost": 4.1 + } /* table_scan */, + "potential_range_indices": [ + { + "index": "PRIMARY", + "usable": true, + "key_parts": [ + "pk" + ] /* key_parts */ + }, + { + "index": "v_idx", + "usable": true, + "key_parts": [ + "v", + "i1" + ] /* key_parts */ + }, + { + "index": "i1_i2_idx", + "usable": true, + "key_parts": [ + "i2", + "i1" + ] /* key_parts */ + } + ] /* potential_range_indices */, + "setup_range_conditions": [ + ] /* setup_range_conditions */, + "group_index_range": { + "chosen": false, + "cause": "not_group_by_or_distinct" + } /* group_index_range */, + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "PRIMARY", + "ranges": [ + "pk < 3" + ] /* ranges */, + "index_only": false, + "records": 2, + "cost": 2.41, + "rowid_ordered": true, + "chosen": true + }, + { + "index": "v_idx", + "ranges": [ + "a <= v <= a AND 1 <= i1 <= 1" + ] /* ranges */, + "index_only": false, + "records": 1, + "cost": 2.21, + "rowid_ordered": true, + "chosen": true + }, + { + "index": "i1_i2_idx", + "ranges": [ + "1 <= i2 <= 1 AND 1 <= i1 <= 1" + ] /* ranges */, + "index_only": false, + "records": 1, + "cost": 2.21, + "rowid_ordered": true, + "chosen": false, + "cause": "cost" + } + ] /* range_scan_alternatives */, + "analyzing_roworder_intersect": { + "intersecting_indices": [ + { + "index": "v_idx", + "usable": true, + "matching_records_now": 1, + "cumulated_cost": 2, + "isect_covering_with_this_index": false + }, + { + "index": "i1_i2_idx", + "usable": true, + "matching_records_now": 0.2, + "cumulated_cost": 2, + "isect_covering_with_this_index": true + } + ] /* intersecting_indices */, + "clustered_pk": { + "clustered_pk_scan_added_to_intersect": true, + "cumulated_cost": 1.1 + } /* clustered_pk */, + "records": 1, + "cost": 1.1, + "covering": false, + "chosen": true + } /* analyzing_roworder_intersect */, + "make_covering_roworder_intersect": { + "included_indices": [ + "v_idx", + "i1_i2_idx" + ] /* included_indices */, + "chosen": false, + "cause": "cost" + } /* make_covering_roworder_intersect */ + } /* analyzing_range_alternatives */, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "index_roworder_intersect", + "records": 1, + "cost": 1.1, + "covering": false, + "clustered_pk_scan": true, + "intersect_of": [ + { + "type": "range_scan", + "index": "v_idx", + "records": 1, + "ranges": [ + "a <= v <= a AND 1 <= i1 <= 1" + ] /* ranges */ + } + ] /* intersect_of */ + } /* range_access_plan */, + "records_for_plan": 1, + "cost_for_plan": 1.1, + "chosen": true + } /* chosen_range_access_summary */ + } /* range_analysis */ + } + ] /* records_estimation */ + }, + { + "considered_execution_plans": "..." + }, + { + "attaching_conditions_to_tables": { + "original_condition": "((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`i2` = 1) and (`test`.`t1`.`i1` = 1) and (`test`.`t1`.`pk` < 3))", + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "database": "test", + "table": "t1", + "attached": "((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`i2` = 1) and (`test`.`t1`.`pk` < 3))" + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "refine_plan": [ + { + "database": "test", + "table": "t1" + } + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 + +DROP TABLE t1; === modified file 'sql/opt_range.cc' --- a/sql/opt_range.cc 2011-05-13 14:17:54 +0000 +++ b/sql/opt_range.cc 2011-05-18 10:37:05 +0000 @@ -5196,17 +5196,12 @@ TRP_ROR_INTERSECT *get_best_covering_ror ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end; DBUG_ENTER("get_best_covering_ror_intersect"); -#if 0 // Jorgen will fix with BUG#12551047 - // None of our tests enter this function - Opt_trace_object (¶m->thd->opt_trace). - add("get_best_covering_roworder_intersect", true). - add("untested_code", true). - add("need_tracing",true); -#endif - if (!param->thd->optimizer_switch_flag(OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)) DBUG_RETURN(NULL); + Opt_trace_object trace_covering (¶m->thd->opt_trace, + "make_covering_roworder_intersect"); + for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan) (*scan)->key_components= param->table->key_info[(*scan)->keynr].key_parts; @@ -5234,9 +5229,10 @@ TRP_ROR_INTERSECT *get_best_covering_ror bool all_covered; DBUG_PRINT("info", ("Building covering ROR-intersection")); - DBUG_EXECUTE("info", print_ror_scans_arr(param->table, - "building covering ROR-I", - ror_scan_mark, ror_scans_end);); + + // Note: trace_idx.end() is called to close this object after this loop. + Opt_trace_array trace_idx(¶m->thd->opt_trace, "included_indices"); + do { /* @@ -5257,33 +5253,55 @@ TRP_ROR_INTERSECT *get_best_covering_ror my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*), (qsort_cmp)cmp_ror_scan_info_covering); - DBUG_EXECUTE("info", print_ror_scans_arr(param->table, - "remaining scans", - ror_scan_mark, ror_scans_end);); - /* I=I-first(I) */ total_cost += (*ror_scan_mark)->index_read_cost; records += (*ror_scan_mark)->records; - DBUG_PRINT("info", ("Adding scan on %s", - param->table->key_info[(*ror_scan_mark)->keynr].name)); + + trace_idx.add_utf8(param->table->key_info[(*ror_scan_mark)->keynr].name); + if (total_cost > read_time) + { + trace_idx.end(); + trace_covering.add("chosen", false).add_alnum("cause", "cost"); DBUG_RETURN(NULL); + } /* F=F-covered by first(I) */ bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields); all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields); } while ((++ror_scan_mark < ror_scans_end) && !all_covered); + + trace_idx.end(); - if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1) + if (!all_covered) + { + trace_covering.add("covering", false).add("chosen", false); DBUG_RETURN(NULL); + } + else + { + trace_covering.add("covering", true); + if (ror_scan_mark < ror_scans_end) + { + Opt_trace_array ota(¶m->thd->opt_trace, "not_included_indices"); + + ROR_SCAN_INFO **remaining_idx= ror_scan_mark; + for (;remaining_idx < ror_scans_end; remaining_idx++) + ota.add_utf8(param->table->key_info[(*remaining_idx)->keynr].name); + } + } + + if ((ror_scan_mark - tree->ror_scans) == 1) + { + trace_covering.add("chosen", false). + add_alnum("cause", "only_one_index"); + DBUG_RETURN(NULL); + } /* Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with cost total_cost. */ DBUG_PRINT("info", ("Covering ROR-intersect scans cost: %g", total_cost)); - DBUG_EXECUTE("info", print_ror_scans_arr(param->table, - "creating covering ROR-intersect", - tree->ror_scans, ror_scan_mark);); /* Add priority queue use cost. */ total_cost += rows2double(records) * @@ -5292,7 +5310,10 @@ TRP_ROR_INTERSECT *get_best_covering_ror DBUG_PRINT("info", ("Covering ROR-intersect full cost: %g", total_cost)); if (total_cost > read_time) + { + trace_covering.add("chosen", false).add_alnum("cause", "cost"); DBUG_RETURN(NULL); + } TRP_ROR_INTERSECT *trp; if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT)) @@ -5310,9 +5331,10 @@ TRP_ROR_INTERSECT *get_best_covering_ror trp->cpk_scan= NULL; set_if_smaller(param->table->quick_condition_rows, records); - DBUG_PRINT("info", - ("Returning covering ROR-intersect plan: cost %g, records %lu", - trp->read_cost, (ulong) trp->records)); + trace_covering.add("records", trp->records). + add("cost", trp->read_cost). + add("chosen", true); + DBUG_RETURN(trp); } --===============7573259012770236934== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/jorgen.loland@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: jorgen.loland@stripped\ # k3hpovzfwciqpkbs # target_branch: file:///export/home/jl208045/mysql/wl4800/mysql-next-\ # mr-opt-backporting-wl4800-12551047/ # testament_sha1: 51cba43eed0ce1490cc9f4f1a623ff1539e104ee # timestamp: 2011-05-18 12:37:09 +0200 # source_branch: file:///export/home/jl208045/mysql/wl4800/mysql-next-\ # mr-opt-backporting-wl4800/ # base_revision_id: guilhem.bichot@stripped\ # 1m0zpn029ejl03ap # # Begin bundle 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 iNBrP/4u5IpwoSHRN6Po --===============7573259012770236934==--