From: Jorgen Loland Date: January 14 2011 3:53pm Subject: bzr commit into mysql-next-mr-bugfixing branch (jorgen.loland:3253) WL#5741 List-Archive: http://lists.mysql.com/commits/128820 Message-Id: <20110114155352.67CC07A3@atum21.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8920029655113483090==" --===============8920029655113483090== 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-range-subselect/ based on revid:jorgen.loland@stripped 3253 Jorgen Loland 2011-01-14 WL#5741: Add optimizer tracing to subqueries * Fix review comments by Guilhem * Update copyright notice. modified: WL4800_TODO.txt mysql-test/r/mysqld--help-notwin.result mysql-test/r/optimizer_trace_no_prot.result mysql-test/r/optimizer_trace_ps_prot.result mysql-test/r/optimizer_trace_range.result mysql-test/r/optimizer_trace_subquery.result mysql-test/suite/sys_vars/r/optimizer_trace_features_basic.result sql/item_subselect.cc sql/item_subselect.h sql/opt_range.cc sql/opt_range.h sql/opt_trace.cc sql/opt_trace.h sql/sql_select.cc === modified file 'WL4800_TODO.txt' --- a/WL4800_TODO.txt 2011-01-12 13:44:58 +0000 +++ b/WL4800_TODO.txt 2011-01-14 15:53:48 +0000 @@ -32,10 +32,6 @@ fix all crashes of --opt-trace-protocol try to avoid the call to get_current_struct in opt_range.cc -solve the problems of "one trace per row scanned" ("range checked for -each record" and subqueries); one example is at the end of -http://lists.mysql.com/commits/124599 - check save_in_field_no_warnings() in opt_range.cc: do we need to disable tracing there? see optimizer_trace_no_prot.result. Jorgen has maybe looked at this in his in-review subquery tracing patch. @@ -53,3 +49,5 @@ range access anyway. Make --opt-trace-protocol dump traces to a separate file so that mtr can run with it without failing all tests. + +Update copyright header of all changed files to reflect changed in 2011 === modified file 'mysql-test/r/mysqld--help-notwin.result' --- a/mysql-test/r/mysqld--help-notwin.result 2011-01-14 13:42:35 +0000 +++ b/mysql-test/r/mysqld--help-notwin.result 2011-01-14 15:53:48 +0000 @@ -872,7 +872,7 @@ optimizer-prune-level 1 optimizer-search-depth 62 optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,materialization=on,semijoin=on,loosescan=on,firstmatch=on,mrr=on,mrr_cost_based=off,index_condition_pushdown=on optimizer-trace -optimizer-trace-features greedy_search=on,range_optimizer=on,dynamic_range=on +optimizer-trace-features greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on optimizer-trace-limit 1 optimizer-trace-max-mem-size 16384 optimizer-trace-offset -1 === modified file 'mysql-test/r/optimizer_trace_no_prot.result' --- a/mysql-test/r/optimizer_trace_no_prot.result 2011-01-14 13:42:35 +0000 +++ b/mysql-test/r/optimizer_trace_no_prot.result 2011-01-14 15:53:48 +0000 @@ -2832,7 +2832,7 @@ explain select * from t1,t2 { } 0 0 select @@optimizer_trace_features; @@optimizer_trace_features -greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on set @@optimizer_trace_features="greedy_search=off"; explain select * from t1,t2; id select_type table type possible_keys key key_len ref rows Extra @@ -3515,6 +3515,34 @@ WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 } ] /* steps */ } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ } ] /* steps */ } /* join_execution */ @@ -4977,6 +5005,20 @@ select * from t1 where (t1.a,t1.b) not i } ] /* steps */ } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ } ] /* steps */ } /* join_execution */ === modified file 'mysql-test/r/optimizer_trace_ps_prot.result' --- a/mysql-test/r/optimizer_trace_ps_prot.result 2011-01-14 13:42:35 +0000 +++ b/mysql-test/r/optimizer_trace_ps_prot.result 2011-01-14 15:53:48 +0000 @@ -2816,7 +2816,7 @@ explain select * from t1,t2 { } 0 0 select @@optimizer_trace_features; @@optimizer_trace_features -greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on set @@optimizer_trace_features="greedy_search=off"; explain select * from t1,t2; id select_type table type possible_keys key key_len ref rows Extra @@ -3499,6 +3499,34 @@ WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 } ] /* steps */ } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ } ] /* steps */ } /* join_execution */ @@ -4953,6 +4981,20 @@ select * from t1 where (t1.a,t1.b) not i } ] /* steps */ } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ } ] /* steps */ } /* join_execution */ === modified file 'mysql-test/r/optimizer_trace_range.result' --- a/mysql-test/r/optimizer_trace_range.result 2011-01-14 13:42:35 +0000 +++ b/mysql-test/r/optimizer_trace_range.result 2011-01-14 15:53:48 +0000 @@ -3450,6 +3450,40 @@ EXPLAIN SELECT 1 FROM "join_execution": { "select#": 2, "steps": [ + { + "records_estimation_per_record": { + "database": "test", + "table": "t2", + "range_analysis": { + "table_scan": { + "records": 3, + "cost": 4.7051 + } /* table_scan */, + "potential_range_indices": [ + { + "index": "b", + "usable": true, + "key_parts": [ + "b" + ] /* key_parts */ + } + ] /* potential_range_indices */, + "best_covering_index_scan": { + "index": "b", + "cost": 1.6465, + "chosen": true + } /* best_covering_index_scan */, + "setup_range_conditions": [ + { + "impossible_condition": { + "cause": "comparison_with_null_always_false" + } /* impossible_condition */ + } + ] /* setup_range_conditions */, + "impossible_range": true + } /* range_analysis */ + } /* records_estimation_per_record */ + } ] /* steps */ } /* join_execution */ }, @@ -3735,6 +3769,20 @@ SELECT * from t1 where topic = all (SELE } ] /* steps */ } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ } ] /* steps */ } /* join_execution */ === modified file 'mysql-test/r/optimizer_trace_subquery.result' --- a/mysql-test/r/optimizer_trace_subquery.result 2011-01-14 13:42:35 +0000 +++ b/mysql-test/r/optimizer_trace_subquery.result 2011-01-14 15:53:48 +0000 @@ -413,6 +413,13 @@ t1.a= (SELECT a FROM t2 LIMIT 1) { } ] /* steps */ } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* subselect_execution */ } ] /* subselect_equality_propagation */, "resulting_condition": "((NULL <> (/* select#3 */ select `test`.`t2`.`a` from `test`.`t2` limit 1)) and multiple equal((/* select#2 */ select NULL from `test`.`t2` limit 1), `test`.`t1`.`a`))" === modified file 'mysql-test/suite/sys_vars/r/optimizer_trace_features_basic.result' --- a/mysql-test/suite/sys_vars/r/optimizer_trace_features_basic.result 2011-01-14 13:42:35 +0000 +++ b/mysql-test/suite/sys_vars/r/optimizer_trace_features_basic.result 2011-01-14 15:53:48 +0000 @@ -1,25 +1,25 @@ SET @start_global_value = @@global.optimizer_trace_features; SELECT @start_global_value; @start_global_value -greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on select @@global.optimizer_trace_features; @@global.optimizer_trace_features -greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on select @@session.optimizer_trace_features; @@session.optimizer_trace_features -greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on show global variables like 'optimizer_trace_features'; Variable_name Value -optimizer_trace_features greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +optimizer_trace_features greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on show session variables like 'optimizer_trace_features'; Variable_name Value -optimizer_trace_features greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +optimizer_trace_features greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on select * from information_schema.global_variables where variable_name='optimizer_trace_features'; VARIABLE_NAME VARIABLE_VALUE -OPTIMIZER_TRACE_FEATURES greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +OPTIMIZER_TRACE_FEATURES greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on select * from information_schema.session_variables where variable_name='optimizer_trace_features'; VARIABLE_NAME VARIABLE_VALUE -OPTIMIZER_TRACE_FEATURES greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +OPTIMIZER_TRACE_FEATURES greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on set global optimizer_trace_features=2; select @@global.optimizer_trace_features; @@global.optimizer_trace_features @@ -49,4 +49,4 @@ ERROR 42000: Variable 'optimizer_trace_f SET @@global.optimizer_trace_features = @start_global_value; SELECT @@global.optimizer_trace_features; @@global.optimizer_trace_features -greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=off +greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on === modified file 'sql/item_subselect.cc' --- a/sql/item_subselect.cc 2011-01-14 13:42:35 +0000 +++ b/sql/item_subselect.cc 2011-01-14 15:53:48 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by === modified file 'sql/item_subselect.h' --- a/sql/item_subselect.h 2011-01-14 13:42:35 +0000 +++ b/sql/item_subselect.h 2011-01-14 15:53:48 +0000 @@ -1,7 +1,7 @@ #ifndef ITEM_SUBSELECT_INCLUDED #define ITEM_SUBSELECT_INCLUDED -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by === modified file 'sql/opt_range.cc' --- a/sql/opt_range.cc 2011-01-14 13:42:35 +0000 +++ b/sql/opt_range.cc 2011-01-14 15:53:48 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1152,7 +1152,9 @@ SQL_SELECT *make_select(TABLE *head, tab } -SQL_SELECT::SQL_SELECT() :quick(0),cond(0),icp_cond(0),free_cond(0) +SQL_SELECT::SQL_SELECT() : + quick(0), cond(0), icp_cond(0), + free_cond(0), traced_before(false) { my_b_clear(&file); } @@ -1169,6 +1171,7 @@ void SQL_SELECT::cleanup() cond= 0; } close_cached_file(&file); + traced_before= false; } @@ -2588,9 +2591,6 @@ int SQL_SELECT::test_quick_select(THD *t if (cond) { { - //Guilhem: this is needed because we might evaluate a subquery - //inside get_mm_tree, but if you have a better suggestion I'm - //all ears. I don't like this tracepoint very much. Opt_trace_array trace_setup_cond(trace, "setup_range_conditions"); tree= get_mm_tree(¶m,cond); } === modified file 'sql/opt_range.h' --- a/sql/opt_range.h 2011-01-03 13:10:02 +0000 +++ b/sql/opt_range.h 2011-01-14 15:53:48 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -856,6 +856,14 @@ class SQL_SELECT :public Sql_alloc { table_map const_tables,read_tables; bool free_cond; + /** + Used by optimizer tracing if this is a subquery: Whether or not + execution of this subselect has been traced by optimizer tracing + already. If optimizer trace option DYNAMIC_RANGE is disabled, + this is used to disable tracing after the first one. + */ + bool traced_before; + SQL_SELECT(); ~SQL_SELECT(); void cleanup(); === modified file 'sql/opt_trace.cc' --- a/sql/opt_trace.cc 2011-01-14 13:42:35 +0000 +++ b/sql/opt_trace.cc 2011-01-14 15:53:48 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -386,9 +386,10 @@ const char *Opt_trace_context::feature_n }; const Opt_trace_context::feature_value Opt_trace_context::FEATURES_DEFAULT= - Opt_trace_context::feature_value(Opt_trace_context::GREEDY_SEARCH | - Opt_trace_context::DYNAMIC_RANGE | - Opt_trace_context::RANGE_OPTIMIZER); + Opt_trace_context::feature_value(Opt_trace_context::GREEDY_SEARCH | + Opt_trace_context::RANGE_OPTIMIZER | + Opt_trace_context::DYNAMIC_RANGE | + Opt_trace_context::REPEATED_SUBSELECT); Opt_trace_context::Opt_trace_context(void): oldest_stmt_to_show(NULL), newest_stmt_to_show(NULL), stmt_to_del(NULL), === modified file 'sql/opt_trace.h' --- a/sql/opt_trace.h 2011-01-14 13:42:35 +0000 +++ b/sql/opt_trace.h 2011-01-14 15:53:48 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2011-01-14 13:42:35 +0000 +++ b/sql/sql_select.cc 2011-01-14 15:53:48 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18436,10 +18436,14 @@ join_init_quick_read_record(JOIN_TAB *ta #ifdef OPTIMIZER_TRACE Opt_trace_context * const trace= tab->join->thd->opt_trace; - const bool trace_enabled= trace ? + const bool repeated_trace_enabled= trace ? trace->feature_enabled(Opt_trace_context::DYNAMIC_RANGE) : false; - Opt_trace_disable_I_S disable_trace_wrapper(trace, !trace_enabled); + const bool disable_trace= + (tab->select->traced_before && !repeated_trace_enabled); + Opt_trace_disable_I_S disable_trace_wrapper(trace, disable_trace); + + tab->select->traced_before= true; Opt_trace_object wrapper(trace); Opt_trace_object trace_table(trace, "records_estimation_per_record"); --===============8920029655113483090== 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\ # m2513pgvsj6d479q # target_branch: file:///export/home/jl208045/mysql/wl4800/mysql-next-\ # mr-opt-backporting-wl4800-range-subselect/ # testament_sha1: e9c544a81a92bea77de7f7c14122cb6a811499e2 # timestamp: 2011-01-14 16:53:52 +0100 # base_revision_id: jorgen.loland@stripped\ # g4gd3g1f694ae2cb # # Begin bundle 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 --===============8920029655113483090==--