1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Change cost for REF to take into account cost for 1 extra key read_next

The main difference in code path between EQ_REF and REF is that for
REF we have to do an extra read_next on the index to check that there
is no more matching rows.

Before this patch we added a preference of EQ_REF by ensuring that REF
would always estimate to find at least 2 rows.

This patch adds the cost of the extra key read_next to REF access and
removes the code that limited REF to at least 2 rows. For some queries
this can have a big effect as the total estimated rows will be halved
for each REF table with 1 rows.

multi_range cost calculations are also changed to take into account
the difference between EQ_REF and REF.

The effect of the patch to the test suite:
- About 80 test case changed
- Almost all changes where for EXPLAIN where estimated rows for REF
  where changed from 2 to 1.
- A few test cases using explain extended had a change of 'filtered'.
  This is because of the estimated rows are now closer to the
  calculated selectivity.
- A very few test had a change of table order.
  This is because the change of estimated rows from 2 to 1 or the small
  cost change for REF
  (main.subselect_sj_jcl6, main.group_by, main.dervied_cond_pushdown,
  main.distinct, main.join_nested, main.order_by, main.join_cache)
- No key statistics and the estimated rows are now smaller which cased
  estimated filtering to be lower.
  (main.subselect_sj_mat)
- The number of total rows are halved.
  (main.derived_cond_pushdown)
- Plans with 1 row changed to use RANGE instead of REF.
  (main.group_min_max)
- ALL changed to REF
  (main.key_diff)
- Key changed from ref + index_only to PRIMARY key for InnoDB, as
  OPTIMIZER_ROW_LOOKUP_COST + OPTIMIZER_ROW_NEXT_FIND_COST is smaller than
  OPTIMIZER_KEY_LOOKUP_COST + OPTIMIZER_KEY_NEXT_FIND_COST.
  (main.join_outer_innodb)
- Cost changes printouts
  (main.opt_trace*)
- Result order change
  (innodb_gis.rtree)
This commit is contained in:
Monty
2022-12-27 14:49:27 +02:00
parent b5df077e85
commit 3fa99f0c0e
81 changed files with 765 additions and 740 deletions

View File

@ -214,7 +214,7 @@ explain extended
select * from t1 join (select * from t2 group by f2) tt on f1=f2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 1 100.00
2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`tt`.`f2` AS `f2`,`tt`.`f22` AS `f22` from `test`.`t1` join (/* select#2 */ select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` group by `test`.`t2`.`f2`) `tt` where `tt`.`f2` = `test`.`t1`.`f1`
@ -228,7 +228,7 @@ flush status;
explain select * from t1 join (select * from t2 group by f2) tt on f1=f2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 1
2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
show status like 'Handler_read%';
Variable_name Value
@ -288,7 +288,7 @@ explain showing created indexes
explain extended select * from t1 join v2 on f1=f2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 1 100.00
2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`v2`.`f2` AS `f2`,`v2`.`f22` AS `f22` from `test`.`t1` join `test`.`v2` where `v2`.`f2` = `test`.`t1`.`f1`
@ -339,7 +339,7 @@ flush status;
explain select * from t1 join v2 on f1=f2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 1
2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
show status like 'Handler_read%';
Variable_name Value
@ -372,7 +372,7 @@ Handler_read_rnd_next 36
explain extended select * from v1 join v4 on f1=f2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 11 100.00 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t2.f2 2 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t2.f2 1 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
Warnings:
Note 1003 /* select#1 */ select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`v1` join `test`.`t2` where `v1`.`f1` = `test`.`t2`.`f2` and `test`.`t2`.`f2` in (2,3)
@ -404,7 +404,7 @@ EXPLAIN
"used_key_parts": ["f1"],
"ref": ["test.t2.f2"],
"loops": 11,
"rows": 2,
"rows": 1,
"cost": "COST_REPLACED",
"filtered": 100,
"materialized": {
@ -569,7 +569,7 @@ join
on x.f1 = z.f1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where
1 PRIMARY <derived5> ref key0 key0 5 tt.f1 2 100.00
1 PRIMARY <derived5> ref key0 key0 5 tt.f1 1 100.00
5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
Warnings:
@ -630,7 +630,7 @@ EXPLAIN
"used_key_parts": ["f1"],
"ref": ["tt.f1"],
"loops": 11,
"rows": 2,
"rows": 1,
"cost": "COST_REPLACED",
"filtered": 100,
"materialized": {
@ -717,7 +717,7 @@ join
on x.f1 = z.f1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00 Using where
1 PRIMARY <derived4> ref key0 key0 5 x.f1 2 100.00
1 PRIMARY <derived4> ref key0 key0 5 x.f1 1 100.00
4 DERIVED <derived5> ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
2 DERIVED <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
@ -806,7 +806,7 @@ EXPLAIN
"used_key_parts": ["f1"],
"ref": ["x.f1"],
"loops": 11,
"rows": 2,
"rows": 1,
"cost": "COST_REPLACED",
"filtered": 100,
"materialized": {
@ -981,7 +981,7 @@ join of above two
explain extended select * from v6 join v7 on f2=f1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 11 100.00 Using where
1 PRIMARY <derived5> ref key0 key0 5 test.t2.f2 2 100.00
1 PRIMARY <derived5> ref key0 key0 5 test.t2.f2 1 100.00
5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22`,`v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`t2` join `test`.`v1` where `v1`.`f1` = `test`.`t2`.`f2` and `test`.`t2`.`f2` < 7 and `test`.`t2`.`f2` in (2,3)
@ -1013,7 +1013,7 @@ EXPLAIN
"used_key_parts": ["f1"],
"ref": ["test.t2.f2"],
"loops": 11,
"rows": 2,
"rows": 1,
"cost": "COST_REPLACED",
"filtered": 100,
"materialized": {
@ -1053,7 +1053,7 @@ test two keys
explain select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 1
1 PRIMARY xx ALL NULL NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join)
2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
@ -1078,7 +1078,7 @@ EXPLAIN
SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index f1 f1 5 NULL 3 Using where; Using index
1 PRIMARY <derived2> ref key0 key0 5 test.t2.f1 2
1 PRIMARY <derived2> ref key0 key0 5 test.t2.f1 1
2 DERIVED t1 ALL NULL NULL NULL NULL 4
SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1;
f1 f1
@ -1275,11 +1275,11 @@ SELECT * FROM t3
WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY <derived3> ref key0 key0 5 test.t2.a 2 100.00 Using where
2 DEPENDENT SUBQUERY <derived3> ref key1 key1 5 func 1 100.00
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
3 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using temporary; Using filesort
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(/* select#2 */ select `v1`.`a` from `test`.`v1` join `test`.`t2` where `v1`.`b` = `test`.`t2`.`a` and <cache>(`test`.`t3`.`a`) = `v1`.`a`)))
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(/* select#2 */ select `v1`.`a` from `test`.`v1` join `test`.`t2` where `test`.`t2`.`a` = `v1`.`b` and <cache>(`test`.`t3`.`a`) = `v1`.`a`)))
SELECT * FROM t3
WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
a
@ -1308,8 +1308,8 @@ FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t4 index f2 f2 9 NULL 2 Using where; Using index; Using temporary; Using filesort
1 PRIMARY t3 ref f2 f2 4 test.t4.f2 2 Using index
1 PRIMARY <derived2> ref key0 key0 4 test.t4.f2 2
1 PRIMARY <derived2> ref key1 key1 4 test.t4.f2 1
1 PRIMARY t3 ref f2 f2 4 test.t4.f2 1 Using index
2 DERIVED t2 system NULL NULL NULL NULL 1 Using temporary
2 DERIVED t1 ref f2 f2 4 const 2 Using where
SELECT t.f1 AS f
@ -1335,7 +1335,7 @@ EXPLAIN
SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t ALL NULL NULL NULL NULL 3 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t.a 2
1 PRIMARY <derived2> ref key0 key0 5 test.t.a 1
2 DERIVED t1 ALL NULL NULL NULL NULL 3
SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
a b a b
@ -1641,7 +1641,7 @@ EXPLAIN
SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 1 FirstMatch(t1)
3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
SELECT * FROM v2;
a b
@ -1940,14 +1940,14 @@ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM t3 t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t index_subquery PRIMARY,c c 8 func,func 2 Using index; Using where
2 DEPENDENT SUBQUERY t index_subquery PRIMARY,c c 8 func,func 1 Using index; Using where
EXPLAIN
SELECT * FROM t1 , t2
WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t3 index_subquery PRIMARY,c c 8 func,func 2 Using index; Using where
2 DEPENDENT SUBQUERY t3 index_subquery PRIMARY,c c 8 func,func 1 Using index; Using where
SELECT * FROM t1 , t2
WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
b a
@ -2014,7 +2014,7 @@ EXPLAIN
SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY <derived3> ref key0 key0 10 test.t1.b,test.t1.a 2 FirstMatch(t1)
1 PRIMARY <derived3> ref key0 key0 10 test.t1.b,test.t1.a 1 FirstMatch(t1)
3 DERIVED t2 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
a b
@ -2068,7 +2068,7 @@ EXPLAIN
SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where; Using filesort
1 PRIMARY <derived3> ref key0 key0 4 v1.b 2
1 PRIMARY <derived3> ref key0 key0 4 v1.b 1
3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
DROP VIEW v1,v2;
@ -2659,7 +2659,7 @@ EXPLAIN EXTENDED
SELECT v1.c1, v1.c2 FROM v1, t2 WHERE v1.c1=t2.c1 AND v1.c2=t2.c2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t2.c2 2 100.00 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t2.c2 1 100.00 Using where
2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00
Warnings:
Note 1003 /* select#1 */ select `v1`.`c1` AS `c1`,`v1`.`c2` AS `c2` from `test`.`v1` join `test`.`t2` where `v1`.`c1` = `test`.`t2`.`c1` and `v1`.`c2` = `test`.`t2`.`c2`
@ -2672,7 +2672,7 @@ SELECT t2.c1, t2.c2 FROM (SELECT c1 g, MAX(c2) m FROM t1 GROUP BY c1) t, t2
WHERE t.g=t2.c1 AND t.m=t2.c2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t2.c2 2 100.00 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t2.c2 1 100.00 Using where
2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00 Using temporary; Using filesort
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from (/* select#2 */ select `test`.`t1`.`c1` AS `g`,max(`test`.`t1`.`c2`) AS `m` from `test`.`t1` group by `test`.`t1`.`c1`) `t` join `test`.`t2` where `t`.`g` = `test`.`t2`.`c1` and `t`.`m` = `test`.`t2`.`c2`
@ -3003,7 +3003,7 @@ GROUP BY mp.pla_id) d
ON d.matintnum=m2.matintnum;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 1
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
prepare stmt1 from
@ -3137,7 +3137,7 @@ EXPLAIN EXTENDED
SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 2 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 1 100.00
2 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t1.id 1 100.00 Using where; Using index
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v2`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v2` on(`v2`.`order_pk` = `test`.`t1`.`id`) where 1
@ -3151,7 +3151,7 @@ EXPLAIN EXTENDED
SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 2 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 1 100.00
2 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t1.id 1 100.00 Using where; Using index
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v3`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v3` on(`v3`.`order_pk` = `test`.`t1`.`id`) where 1