From 4515a89814adaa61b26a900086a54b8cf51f188a Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 16 Jun 2022 13:12:01 +0300 Subject: [PATCH] Fixed cost calculations for materialized tables One effect of this change in the test suite is that tests with very few rows changed to use sub queries instead of materialization. This is correct and expected as for these the materialization overhead is too high. A lot of tests where fixed to still use materialization by adding a few rows to the tables (most tests has only 2-3 rows and are thus easily affected when cost computations are changed). Other things: - Added more variables to TMPTABLE_COSTS for better cost calculation - Added cost of copying rows to TMPTABLE_COSTS lookup and write - Added THD::optimizer_cache_hit_ratio for easier cost calculations - Added DISK_FAST_READ_SIZE to be used when calculating costs when reading big blocks from a disk --- mysql-test/include/explain_non_select.inc | 6 +- mysql-test/include/index_merge1.inc | 2 +- mysql-test/main/cte_nonrecursive.result | 8 +- mysql-test/main/derived_cond_pushdown.result | 10 +- mysql-test/main/derived_cond_pushdown.test | 2 +- mysql-test/main/explain_json.result | 32 ++-- mysql-test/main/index_merge_myisam.result | 4 +- .../main/myisam_explain_non_select_all.result | 34 ++-- mysql-test/main/opt_trace.result | 156 ++++++++++++------ mysql-test/main/order_by.result | 18 +- mysql-test/main/order_by.test | 2 +- mysql-test/main/subselect.result | 23 ++- mysql-test/main/subselect.test | 16 +- mysql-test/main/subselect3.inc | 11 +- mysql-test/main/subselect3.result | 20 ++- mysql-test/main/subselect3_jcl6.result | 20 ++- mysql-test/main/subselect4.result | 36 ++-- mysql-test/main/subselect4.test | 8 +- mysql-test/main/subselect_exists2in.result | 19 ++- mysql-test/main/subselect_exists2in.test | 12 +- mysql-test/main/subselect_mat.result | 16 +- mysql-test/main/subselect_mat_cost.result | 40 +---- mysql-test/main/subselect_mat_cost.test | 8 +- .../main/subselect_no_exists_to_in.result | 18 +- mysql-test/main/subselect_no_mat.result | 18 +- mysql-test/main/subselect_no_opts.result | 18 +- mysql-test/main/subselect_no_scache.result | 23 ++- mysql-test/main/subselect_no_semijoin.result | 42 +++-- .../main/subselect_partial_match.result | 18 +- mysql-test/main/subselect_partial_match.test | 8 +- mysql-test/main/subselect_sj.result | 23 +-- mysql-test/main/subselect_sj.test | 2 +- mysql-test/main/subselect_sj2.result | 19 ++- mysql-test/main/subselect_sj2.test | 15 +- mysql-test/main/subselect_sj2_jcl6.result | 24 ++- mysql-test/main/subselect_sj2_mat.result | 35 ++-- mysql-test/main/subselect_sj2_mat.test | 2 +- mysql-test/main/subselect_sj_jcl6.result | 23 +-- mysql-test/main/subselect_sj_mat.result | 37 ++--- mysql-test/main/type_time_6065.result | 5 +- mysql-test/main/view.test | 3 +- sql/handler.cc | 3 +- sql/opt_split.cc | 2 +- sql/opt_subselect.cc | 66 +++++--- sql/optimizer_costs.h | 4 +- sql/sql_class.cc | 2 +- sql/sql_class.h | 2 + sql/sql_const.h | 6 + sql/sql_select.h | 5 +- sql/sys_vars.cc | 11 +- 50 files changed, 566 insertions(+), 371 deletions(-) diff --git a/mysql-test/include/explain_non_select.inc b/mysql-test/include/explain_non_select.inc index d22310c9813..9ce620a72de 100644 --- a/mysql-test/include/explain_non_select.inc +++ b/mysql-test/include/explain_non_select.inc @@ -73,11 +73,11 @@ INSERT INTO t2 VALUES (1), (2), (3); --source include/explain_utils.inc DROP TABLE t1, t2; ---echo #7 +--echo #7a CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); CREATE TABLE t2 (b INT); -INSERT INTO t2 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (1), (2), (3), (1000); --let $query = UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3) --let $select = SELECT * FROM t1, t2 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3) --source include/explain_utils.inc @@ -197,7 +197,7 @@ DROP TABLE t1, t2, t3; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); CREATE TABLE t2 (a INT); -INSERT INTO t2 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (1), (2), (3), (1000); --let $query = UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2) --let $select = SELECT * FROM t1 WHERE a IN (SELECT a FROM t2) --source include/explain_utils.inc diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index 91609f628ca..199fc9d3b2f 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -517,7 +517,7 @@ DROP TABLE t1; create table t1 (a int); insert into t1 values (1),(2); create table t2(a int, b int); -insert into t2 values (1,1), (2, 1000); +insert into t2 values (1,1), (2, 1000),(5000,5000); create table t3 (a int, b int, filler char(100), key(a), key(b)); insert into t3 select 1000, 1000,'filler' from seq_1_to_1000; diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index 4c0aa2e8cf3..58418cc7d9d 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -418,8 +418,8 @@ t2.c in (with t as (select * from t1 where t1.a<5) select t2.c from t2,t where t2.c=t.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 -1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where 3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) explain @@ -430,8 +430,8 @@ from t2,(select * from t1 where t1.a<5) as t where t2.c=t.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 -1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) # two different definitions of t: one in the with clause of the main query, @@ -461,8 +461,8 @@ t.c in (with t as (select * from t1 where t1.a<5) select t2.c from t2,t where t2.c=t.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 4 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where 4 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) explain @@ -472,8 +472,8 @@ t.c in (select t2.c from t2, (select * from t1 where t1.a<5) as t where t2.c=t.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where 3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) # another with table tt is defined in the with clause of a subquery diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index b60359f074c..ce0338bee1f 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -19723,7 +19723,7 @@ create table t1 (id int, a int, index (a), index (id, a)) engine=myisam; insert into t1 values (17,1),(17,3010),(17,3013),(17,3053),(21,2446),(21,2467),(21,2); create table t2 (a int) engine=myisam; -insert into t2 values (1),(2),(3); +insert into t2 values (1),(2),(3),(1000),(2000),(3000); create table t3 (id int) engine=myisam; insert into t3 values (1),(2); analyze table t1,t2,t3; @@ -19747,7 +19747,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ref a a 5 test.t3.id 1 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY ref key0 key0 5 test.t3.id 2 -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 2 DERIVED cp2 index NULL a 5 NULL 7 Using index explain format=json select * from t1, (select a from t1 cp2 group by a) dt, t3 where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); @@ -19798,7 +19798,7 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", - "rows": 3, + "rows": 6, "filtered": 100 } } @@ -19855,7 +19855,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ref a a 5 test.t3.id 1 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY ref key0 key0 5 test.t3.id 2 -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 2 LATERAL DERIVED cp2 ref a a 5 test.t1.a 1 Using where; Using index explain format=json select * from t1, (select a from t1 cp2 group by a) dt, t3 where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); @@ -19906,7 +19906,7 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", - "rows": 3, + "rows": 6, "filtered": 100 } } diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index a09fd1b59e3..83e784c3450 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -3601,7 +3601,7 @@ insert into t1 values (17,1),(17,3010),(17,3013),(17,3053),(21,2446),(21,2467),(21,2); create table t2 (a int) engine=myisam; -insert into t2 values (1),(2),(3); +insert into t2 values (1),(2),(3),(1000),(2000),(3000); create table t3 (id int) engine=myisam; insert into t3 values (1),(2); diff --git a/mysql-test/main/explain_json.result b/mysql-test/main/explain_json.result index fde96bc1a14..d861eff05f1 100644 --- a/mysql-test/main/explain_json.result +++ b/mysql-test/main/explain_json.result @@ -728,19 +728,6 @@ EXPLAIN "filtered": 100 } }, - { - "block-nl-join": { - "table": { - "table_name": "t2", - "access_type": "ALL", - "rows": 10, - "filtered": 100 - }, - "buffer_type": "flat", - "buffer_size": "119", - "join_type": "BNL" - } - }, { "table": { "table_name": "", @@ -769,6 +756,19 @@ EXPLAIN } } } + }, + { + "block-nl-join": { + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 10, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "1Kb", + "join_type": "BNL" + } } ] } @@ -1078,7 +1078,7 @@ EXPLAIN "access_type": "ALL", "rows": 2, "filtered": 100, - "attached_condition": "!(t1.a,t1.a in (subquery#2))" + "attached_condition": "!(t1.a,(subquery#2))" } } ], @@ -1086,13 +1086,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "having_condition": "trigcond(t2.b is null)", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", "rows": 2, - "filtered": 100 + "filtered": 100, + "attached_condition": "trigcond((t1.a) = t2.b or t2.b is null)" } } ] diff --git a/mysql-test/main/index_merge_myisam.result b/mysql-test/main/index_merge_myisam.result index 7d10500d34d..30bda34ec0b 100644 --- a/mysql-test/main/index_merge_myisam.result +++ b/mysql-test/main/index_merge_myisam.result @@ -554,7 +554,7 @@ DROP TABLE t1; create table t1 (a int); insert into t1 values (1),(2); create table t2(a int, b int); -insert into t2 values (1,1), (2, 1000); +insert into t2 values (1,1), (2, 1000),(5000,5000); create table t3 (a int, b int, filler char(100), key(a), key(b)); insert into t3 select 1000, 1000,'filler' from seq_1_to_1000; insert into t3 values (1,1,'data'); @@ -566,7 +566,7 @@ where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 2 MATERIALIZED t3 ALL a,b NULL NULL NULL 1002 Range checked for each record (index map: 0x3) select * from t1 where exists (select 1 from t2, t3 diff --git a/mysql-test/main/myisam_explain_non_select_all.result b/mysql-test/main/myisam_explain_non_select_all.result index f14676bb394..98bb644fd5f 100644 --- a/mysql-test/main/myisam_explain_non_select_all.result +++ b/mysql-test/main/myisam_explain_non_select_all.result @@ -327,11 +327,11 @@ Handler_read_rnd_next 7 Handler_update 2 DROP TABLE t1, t2; -#7 +#7a CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); CREATE TABLE t2 (b INT); -INSERT INTO t2 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (1), (2), (3), (1000); # # query: UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3) # select: SELECT * FROM t1, t2 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3) @@ -341,17 +341,17 @@ Warning 1287 ' INTO ;' is deprecated and will be removed in a future release. Please use 'SELECT INTO ;' is deprecated and will be EXPLAIN UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where FLUSH STATUS; FLUSH TABLES; EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using where # Status of EXPLAIN EXTENDED query Variable_name Value Handler_read_key 4 @@ -1004,7 +1004,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 100.00 Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where 1 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution @@ -1015,7 +1015,7 @@ Warning 1287 '