Skip to content

Commit

Permalink
Update cost for hash and cached joins
Browse files Browse the repository at this point in the history
The old code did not't correctly add TIME_FOR_COMPARE to rows that are
part of the scan that will be compared with the attached where clause.

Now the cost calculation for hash join and full join cache join are
identical except for HASH_FANOUT (10%)

The cost for a join with keys is now also uniform.
The total cost for a using a key for lookup is calculated in one place as:

(cost_of_finding_rows_through_key(records) + records/TIME_FOR_COMPARE)*
record_count_of_previous_row_combinations + startup_cost

startup_cost is the cost of a creating a temporary table (if needed)

Best_cost now includes the cost of comparing all WHERE clauses and also
cost of joining with previous row combinations.

Other things:
- Optimizer trace is now printing the total costs, including testing the
  WHERE clause (TIME_FOR_COMPARE) and comparing with all previous rows.
- In optimizer trace, include also total cost of query together with the
  final join order. This makes it easier to find out where the cost was
  calculated.
- Old code used filter even if the cost for it was higher than not using a
  filter. This is not corrected.
- When rebasing on 10.11, I noticed some changes to access_cost_factor
  calculation. These changes was not picked as the coming changes
  to filtering will make that code obsolete.
  • Loading branch information
montywi authored and spetrunia committed Feb 2, 2023
1 parent 6fa7451 commit 9569809
Show file tree
Hide file tree
Showing 72 changed files with 1,438 additions and 1,370 deletions.
18 changes: 9 additions & 9 deletions mysql-test/main/cte_recursive.result
Original file line number Diff line number Diff line change
Expand Up @@ -692,14 +692,14 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived3> ref key0 key0 5 c.h_id 2 100.00
1 PRIMARY <derived3> ref key0 key0 5 c.w_id 2 100.00
3 DERIVED folks ALL NULL NULL NULL NULL 12 100.00 Using where
4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
4 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
5 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
5 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
4 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00
4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 75.00 Using where; Using join buffer (flat, BNL join)
5 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00
5 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 75.00 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union3,4,5> ALL NULL NULL NULL NULL NULL NULL
2 DERIVED <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
Warnings:
Note 1003 with recursive ancestor_couple_ids(`h_id`,`w_id`) as (/* select#2 */ select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors(`id`,`name`,`dob`,`father`,`mother`) as (/* select#3 */ select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all /* select#4 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `test`.`p`.`id` = `fa`.`h_id` union all /* select#5 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `test`.`p`.`id` = `ma`.`w_id`)/* select#1 */ select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id`
Note 1003 with recursive ancestor_couple_ids(`h_id`,`w_id`) as (/* select#2 */ select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors(`id`,`name`,`dob`,`father`,`mother`) as (/* select#3 */ select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all /* select#4 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `fa`.`h_id` = `test`.`p`.`id` union all /* select#5 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `ma`.`w_id` = `test`.`p`.`id`)/* select#1 */ select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id`
# simple mutual recursion
with recursive
ancestor_couple_ids(h_id, w_id)
Expand Down Expand Up @@ -3260,10 +3260,10 @@ ORDER BY path;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 15 Using filesort
2 DERIVED t2 ALL NULL NULL NULL NULL 15 Using where
3 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 15
3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
4 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 15
4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
3 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 15 Using where
3 RECURSIVE UNION <derived2> ref key0 key0 5 test.t2.id 2
4 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 15 Using where
4 RECURSIVE UNION <derived2> ref key0 key0 5 test.t2.id 2
NULL UNION RESULT <union2,3,4> ALL NULL NULL NULL NULL NULL
DROP TABLE t1,t2;
set tmp_memory_table_size=default;
Expand Down
6 changes: 3 additions & 3 deletions mysql-test/main/delete.result
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,13 @@ insert into t3 values (1,1),(2,1),(1,3);
select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
a b a b a b
1 1 1 1 1 1
1 3 1 1 1 3
2 1 2 2 2 1
1 3 1 1 1 3
explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
1 SIMPLE t2 index PRIMARY PRIMARY 8 NULL 3 Using where; Using index; Using join buffer (flat, BNL join)
1 SIMPLE t3 index PRIMARY PRIMARY 8 NULL 3 Using where; Using index; Using join buffer (incremental, BNL join)
1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t2.b,test.t1.b 1 Using index
delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
select * from t3;
a b
Expand Down
39 changes: 20 additions & 19 deletions mysql-test/main/derived_cond_pushdown.result
Original file line number Diff line number Diff line change
Expand Up @@ -17764,10 +17764,10 @@ from t1 left join
on t1.a=t.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 9 100.00 Using where
2 DERIVED t2 ALL idx_a NULL NULL NULL 90 100.00 Using temporary; Using filesort
1 PRIMARY <derived2> ref key0 key0 5 test.t1.a 2 100.00 Using where
2 LATERAL DERIVED t2 ref idx_a idx_a 5 test.t1.a 1 100.00
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t1` left join (/* select#2 */ select `test`.`t2`.`a` AS `a`,max(`test`.`t2`.`b`) AS `max`,min(`test`.`t2`.`b`) AS `min` from `test`.`t2` group by `test`.`t2`.`a`) `t` on(`t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`a` is not null) where 1
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t1` left join (/* select#2 */ select `test`.`t2`.`a` AS `a`,max(`test`.`t2`.`b`) AS `max`,min(`test`.`t2`.`b`) AS `min` from `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` group by `test`.`t2`.`a`) `t` on(`t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`a` is not null) where 1
explain format=json select t1.a,t.max,t.min
from t1 left join
(select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t
Expand Down Expand Up @@ -17795,28 +17795,29 @@ EXPLAIN
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t1.a"],
"rows": 9,
"rows": 2,
"filtered": 100,
"attached_condition": "trigcond(trigcond(t1.a is not null))",
"materialized": {
"lateral": 1,
"query_block": {
"select_id": 2,
"filesort": {
"sort_key": "t2.a",
"temporary_table": {
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"possible_keys": ["idx_a"],
"rows": 90,
"filtered": 100
}
}
]
"outer_ref_condition": "t1.a is not null",
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ref",
"possible_keys": ["idx_a"],
"key": "idx_a",
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t1.a"],
"rows": 1,
"filtered": 100
}
}
}
]
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions mysql-test/main/derived_split_innodb.result
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ t2
where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 1
1 PRIMARY <derived2> ref key1 key1 4 test.t2.id 2
1 PRIMARY t1 ALL idx NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t1 ref idx idx 4 test.t2.id 1
1 PRIMARY <derived2> ref key0 key0 9 test.t2.id,test.t1.id 2
2 DERIVED t3 ref idx1,idx2 idx1 4 const 5 Using where; Using index
select t1.id, t1.itemid, dt.id, t2.id
from t1,
Expand All @@ -227,8 +227,8 @@ t2
where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 1
1 PRIMARY <derived2> ref key1 key1 4 test.t2.id 2
1 PRIMARY t1 ALL idx NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t1 ref idx idx 4 test.t2.id 1
1 PRIMARY <derived2> ref key0 key0 9 test.t2.id,test.t1.id 2
2 DERIVED t3 ref idx1 idx1 4 const 5 Using where; Using index
select t1.id, t1.itemid, dt.id, t2.id
from t1,
Expand Down
24 changes: 11 additions & 13 deletions mysql-test/main/derived_view.result
Original file line number Diff line number Diff line change
Expand Up @@ -2044,10 +2044,16 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t5 ALL NULL NULL NULL NULL 2
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
1 SIMPLE t3 ref e e 3 test.t2.d 1 Using index
1 SIMPLE t4 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 index e e 7 NULL 8 Using where; Using index; Using join buffer (flat, BNL join)
SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
d
w
w
w
w
w
w
d
d
d
Expand All @@ -2066,12 +2072,6 @@ e
e
e
e
w
w
w
w
w
w
SET SESSION join_cache_level = @exit_join_cache_level;
SET SESSION join_buffer_size = @exit_join_buffer_size;
DROP VIEW v3;
Expand Down Expand Up @@ -2459,8 +2459,6 @@ SELECT * FROM t1;
a
1
1
1
1
drop table t1,t2;
set optimizer_switch=@save968720_optimizer_switch;
#
Expand Down Expand Up @@ -2597,8 +2595,8 @@ CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
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
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 75.00 Using where; Using join buffer (flat, BNL join)
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
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`
Expand All @@ -2610,8 +2608,8 @@ EXPLAIN EXTENDED
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
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 75.00 Using where; Using join buffer (flat, BNL join)
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
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`
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/main/distinct.result
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2
WHERE t1_1.a = t1_2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1_1 ALL PRIMARY NULL NULL NULL 3 Using temporary
1 SIMPLE t1_2 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index; Using join buffer (flat, BNL join)
1 SIMPLE t1_2 eq_ref PRIMARY PRIMARY 4 test.t1_1.a 1 Using index; Distinct
EXPLAIN SELECT a FROM t1 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 4 NULL 3 Using index
Expand Down
12 changes: 6 additions & 6 deletions mysql-test/main/fetch_first.result
Original file line number Diff line number Diff line change
Expand Up @@ -1007,12 +1007,12 @@ id first_name last_name score
3 John Smith 6
select * from t1 order by first_name desc fetch first 3 rows with ties;
id first_name last_name score
8 Silvia Ganush 10
2 John Doe 6
3 John Smith 6
4 John Smith 6
5 John Smith 7
6 John Elton 8.1
# Silvia # #
# John # #
# John # #
# John # #
# John # #
# John # #
(select * from t1 order by 1 fetch first 3 rows with ties)
intersect
(select * from t1 order by first_name desc fetch first 3 rows with ties)
Expand Down
1 change: 1 addition & 0 deletions mysql-test/main/fetch_first.test
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ fetch first 1 row with ties;
--echo # Test union-like operator with multiple fetch first clauses.
--echo #
select * from t1 order by 1 fetch first 3 rows with ties;
--replace_column 1 # 3 # 4 #
select * from t1 order by first_name desc fetch first 3 rows with ties;

--sorted_result
Expand Down
Loading

0 comments on commit 9569809

Please sign in to comment.