Browse Source

Fixed costs in JOIN_TAB::estimate_scan_time() and HEAP

MDEV-35958 Cost estimates for materialized derived tables are poor

Estimate_scan_time() calculates the cost of scanning a derivied table.
The old code did not take into account that the temporary table heap table
may be converted to Aria.

Things fixed:
- Added checking if the temporary tables data will fit in the heap.
  If not, then calculate the cost based on the designated internal
  temporary table engine (Aria).
- Removed MY_MAX(records, 1000) and instead trust the optimizer's
  estimate of records. This reduces the cost of temporary tables a bit
  for small tables, which caused a few changes in mtr results.
- Fixed cost calculation for HEAP.
  - HEAP costs->row_next_find_cost was not set. This does not affect old
    costs calculation as this cost slot was not used anywhere.
    Now HEAP cost->row_next_find_cost is set, which allowed me to remove
    some duplicated computation in ha_heap::scan_time()

Reviewed by: Sergei Petrunia <sergey@mariadb.com>
pull/3487/merge
Monty 8 months ago
parent
commit
74f70c3944
  1. 31
      mysql-test/main/cte_recursive.result
  2. 8
      mysql-test/main/derived.result
  3. 323
      mysql-test/main/derived_cond_pushdown.result
  4. 100
      mysql-test/main/opt_trace.result
  5. 6
      mysql-test/main/opt_tvc.result
  6. 2
      mysql-test/main/optimizer_costs.result
  7. 6
      mysql-test/main/subselect_sj.result
  8. 8
      mysql-test/main/subselect_sj_jcl6.result
  9. 52
      sql/sql_select.cc
  10. 6
      storage/heap/ha_heap.cc

31
mysql-test/main/cte_recursive.result

@ -3915,8 +3915,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
1 PRIMARY <derived3> ref key0 key0 23 test.t1.a1 1 FirstMatch(t1)
3 DERIVED t2 const PRIMARY PRIMARY 22 const 1 Using index
4 RECURSIVE UNION tt2 ALL b1 NULL NULL NULL 14 Using where
4 RECURSIVE UNION <derived3> ref key0 key0 23 test.tt2.b1 1
4 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 2 Using where
4 RECURSIVE UNION tt2 ref b1 b1 23 cte.a2 1
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
analyze format=json select fv
from (select t1.a1, f1(t1.a2) fv from t1) dt
@ -4018,39 +4018,38 @@ ANALYZE
"nested_loop": [
{
"table": {
"table_name": "tt2",
"table_name": "<derived3>",
"access_type": "ALL",
"possible_keys": ["b1"],
"loops": 1,
"r_loops": 1,
"rows": 14,
"r_rows": 14,
"rows": 2,
"r_rows": 1,
"cost": "REPLACED",
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
"r_engine_stats": REPLACED,
"filtered": 100,
"r_total_filtered": 100,
"attached_condition": "tt2.b1 is not null",
"attached_condition": "cte.a2 is not null",
"r_filtered": 100
}
},
{
"table": {
"table_name": "<derived3>",
"table_name": "tt2",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"possible_keys": ["b1"],
"key": "b1",
"key_length": "23",
"used_key_parts": ["a2"],
"ref": ["test.tt2.b1"],
"loops": 14,
"r_loops": 14,
"used_key_parts": ["b1"],
"ref": ["cte.a2"],
"loops": 2,
"r_loops": 1,
"rows": 1,
"r_rows": 0.071428571,
"r_rows": 1,
"cost": "REPLACED",
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
"r_engine_stats": REPLACED,
"filtered": 100,
"r_total_filtered": 100,
"r_filtered": 100

8
mysql-test/main/derived.result

@ -2469,7 +2469,7 @@ EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.023260307,
"cost": 0.020930975,
"nested_loop": [
{
"table": {
@ -2477,7 +2477,7 @@ EXPLAIN
"access_type": "ALL",
"loops": 1,
"rows": 2,
"cost": 0.012418701,
"cost": 0.010089369,
"filtered": 100,
"attached_condition": "d2.e1 = 1",
"materialized": {
@ -3226,7 +3226,7 @@ EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.012418701,
"cost": 0.010089369,
"nested_loop": [
{
"table": {
@ -3234,7 +3234,7 @@ EXPLAIN
"access_type": "ALL",
"loops": 1,
"rows": 2,
"cost": 0.012418701,
"cost": 0.010089369,
"filtered": 100,
"attached_condition": "f.c3 + 1 > 10 and f.c1 > 1 and f.c2 > 123",
"materialized": {

323
mysql-test/main/derived_cond_pushdown.result

@ -3634,42 +3634,42 @@ set statement optimizer_switch='condition_pushdown_for_derived=off' for select *
((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b);
a b max_c avg_c a b max_c avg_c a b c d
6 20 315 279.3333 6 20 315 279.3333 2 3 207 207
6 20 315 279.3333 6 20 315 279.3333 1 21 909 12
6 20 315 279.3333 6 20 315 279.3333 7 13 312 406
6 20 315 279.3333 6 20 315 279.3333 6 20 315 279
6 20 315 279.3333 6 20 315 279.3333 1 19 203 107
6 20 315 279.3333 6 20 315 279.3333 3 12 231 190
6 20 315 279.3333 6 20 315 279.3333 6 23 303 909
8 33 404 213.6667 8 33 404 213.6667 2 3 207 207
6 20 315 279.3333 6 20 315 279.3333 1 21 909 12
8 33 404 213.6667 8 33 404 213.6667 1 21 909 12
6 20 315 279.3333 6 20 315 279.3333 7 13 312 406
8 33 404 213.6667 8 33 404 213.6667 7 13 312 406
6 20 315 279.3333 6 20 315 279.3333 6 20 315 279
8 33 404 213.6667 8 33 404 213.6667 6 20 315 279
6 20 315 279.3333 6 20 315 279.3333 1 19 203 107
8 33 404 213.6667 8 33 404 213.6667 1 19 203 107
6 20 315 279.3333 6 20 315 279.3333 3 12 231 190
8 33 404 213.6667 8 33 404 213.6667 3 12 231 190
6 20 315 279.3333 6 20 315 279.3333 6 23 303 909
8 33 404 213.6667 8 33 404 213.6667 6 23 303 909
select * from v1,v2,t2 where
((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b);
a b max_c avg_c a b max_c avg_c a b c d
6 20 315 279.3333 6 20 315 279.3333 2 3 207 207
6 20 315 279.3333 6 20 315 279.3333 1 21 909 12
6 20 315 279.3333 6 20 315 279.3333 7 13 312 406
6 20 315 279.3333 6 20 315 279.3333 6 20 315 279
6 20 315 279.3333 6 20 315 279.3333 1 19 203 107
6 20 315 279.3333 6 20 315 279.3333 3 12 231 190
6 20 315 279.3333 6 20 315 279.3333 6 23 303 909
8 33 404 213.6667 8 33 404 213.6667 2 3 207 207
6 20 315 279.3333 6 20 315 279.3333 1 21 909 12
8 33 404 213.6667 8 33 404 213.6667 1 21 909 12
6 20 315 279.3333 6 20 315 279.3333 7 13 312 406
8 33 404 213.6667 8 33 404 213.6667 7 13 312 406
6 20 315 279.3333 6 20 315 279.3333 6 20 315 279
8 33 404 213.6667 8 33 404 213.6667 6 20 315 279
6 20 315 279.3333 6 20 315 279.3333 1 19 203 107
8 33 404 213.6667 8 33 404 213.6667 1 19 203 107
6 20 315 279.3333 6 20 315 279.3333 3 12 231 190
8 33 404 213.6667 8 33 404 213.6667 3 12 231 190
6 20 315 279.3333 6 20 315 279.3333 6 23 303 909
8 33 404 213.6667 8 33 404 213.6667 6 23 303 909
explain select * from v1,v2,t2 where
((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <derived3> ref key0 key0 5 v1.b 2 Using where
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where
1 PRIMARY <derived3> ref key0 key0 5 v1.b 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join)
3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort
explain format=json select * from v1,v2,t2 where
@ -3681,29 +3681,13 @@ EXPLAIN
"cost": "COST_REPLACED",
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 1,
"rows": 9,
"cost": "COST_REPLACED",
"filtered": 100,
"attached_condition": "t2.b < 50"
}
},
{
"block-nl-join": {
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"loops": 9,
"loops": 1,
"rows": 20,
"cost": "COST_REPLACED",
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "238",
"join_type": "BNL",
"filtered": 100,
"attached_condition": "v1.b is not null",
"materialized": {
"query_block": {
@ -3740,11 +3724,10 @@ EXPLAIN
"key_length": "5",
"used_key_parts": ["b"],
"ref": ["v1.b"],
"loops": 180,
"loops": 20,
"rows": 2,
"cost": "COST_REPLACED",
"filtered": 100,
"attached_condition": "v2.a = v1.a or v1.a = t2.a",
"materialized": {
"query_block": {
"select_id": 3,
@ -3771,6 +3754,23 @@ EXPLAIN
}
}
}
},
{
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 40,
"rows": 9,
"cost": "COST_REPLACED",
"filtered": 100,
"attached_condition": "t2.b < 50"
},
"buffer_type": "flat",
"buffer_size": "1Kb",
"join_type": "BNL",
"attached_condition": "v2.a = v1.a or t2.a = v1.a"
}
}
]
}
@ -4158,9 +4158,9 @@ select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b);
a b max_c avg_c a b max_c avg_c a b c d
explain select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 9
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where
1 PRIMARY <derived3> ref key0 key0 5 v1.b 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using join buffer (flat, BNL join)
3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
explain format=json select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b);
@ -4171,30 +4171,14 @@ EXPLAIN
"cost": "COST_REPLACED",
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 1,
"rows": 9,
"cost": "COST_REPLACED",
"filtered": 100
}
},
{
"block-nl-join": {
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"loops": 9,
"loops": 1,
"rows": 20,
"cost": "COST_REPLACED",
"filtered": 100,
"attached_condition": "v1.a = 1 and v1.b > 10"
},
"buffer_type": "flat",
"buffer_size": "238",
"join_type": "BNL",
"attached_condition": "v1.b is not null",
"attached_condition": "v1.a = 1 and v1.b > 10 and v1.b is not null",
"materialized": {
"query_block": {
"select_id": 2,
@ -4231,7 +4215,7 @@ EXPLAIN
"key_length": "5",
"used_key_parts": ["b"],
"ref": ["v1.b"],
"loops": 180,
"loops": 20,
"rows": 2,
"cost": "COST_REPLACED",
"filtered": 100,
@ -4261,6 +4245,21 @@ EXPLAIN
}
}
}
},
{
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 40,
"rows": 9,
"cost": "COST_REPLACED",
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "1Kb",
"join_type": "BNL"
}
}
]
}
@ -4737,10 +4736,10 @@ where t1.a<8 group by a,b) v3,
t2 where (v1.a=v2.a) and (v1.b=v3.b) and ((v3.avg_c>170) or (v3.a<5))
and ((v1.avg_c<400) or (v1.a>1)) and (v2.min_c<200);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 9
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where
1 PRIMARY <derived3> ref key0 key0 5 v1.a 2 Using where
1 PRIMARY <derived4> ref key0 key0 5 v1.b 2 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using join buffer (flat, BNL join)
4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
@ -4760,29 +4759,13 @@ EXPLAIN
"cost": "COST_REPLACED",
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 1,
"rows": 9,
"cost": "COST_REPLACED",
"filtered": 100
}
},
{
"block-nl-join": {
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"loops": 9,
"loops": 1,
"rows": 20,
"cost": "COST_REPLACED",
"filtered": 100,
"attached_condition": "v1.avg_c < 400 or v1.a > 1"
},
"buffer_type": "flat",
"buffer_size": "238",
"join_type": "BNL",
"attached_condition": "(v1.avg_c < 400 or v1.a > 1) and v1.a is not null and v1.b is not null",
"materialized": {
"query_block": {
@ -4820,7 +4803,7 @@ EXPLAIN
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["v1.a"],
"loops": 180,
"loops": 20,
"rows": 2,
"cost": "COST_REPLACED",
"filtered": 100,
@ -4861,7 +4844,7 @@ EXPLAIN
"key_length": "5",
"used_key_parts": ["b"],
"ref": ["v1.b"],
"loops": 360,
"loops": 40,
"rows": 2,
"cost": "COST_REPLACED",
"filtered": 100,
@ -4892,6 +4875,21 @@ EXPLAIN
}
}
}
},
{
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 80,
"rows": 9,
"cost": "COST_REPLACED",
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "4Kb",
"join_type": "BNL"
}
}
]
}
@ -7796,104 +7794,104 @@ set statement optimizer_switch='condition_pushdown_for_derived=off' for select *
(((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a);
a b min_c a b max_c avg_c a b c d
1 19 107 1 21 500 234.6000 2 3 207 207
1 19 107 1 21 500 234.6000 1 21 909 12
1 19 107 1 21 500 234.6000 7 13 312 406
1 19 107 1 21 500 234.6000 8 64 248 107
1 19 107 1 21 500 234.6000 6 20 315 279
1 19 107 1 21 500 234.6000 1 19 203 107
1 19 107 1 21 500 234.6000 8 80 800 314
1 19 107 1 21 500 234.6000 3 12 231 190
1 19 107 1 21 500 234.6000 6 23 303 909
5 16 207 5 16 207 207.0000 2 3 207 207
5 16 207 5 16 207 207.0000 1 21 909 12
5 16 207 5 16 207 207.0000 7 13 312 406
5 16 207 5 16 207 207.0000 8 64 248 107
5 16 207 5 16 207 207.0000 6 20 315 279
5 16 207 5 16 207 207.0000 1 19 203 107
5 16 207 5 16 207 207.0000 8 80 800 314
5 16 207 5 16 207 207.0000 3 12 231 190
5 16 207 5 16 207 207.0000 6 23 303 909
5 27 132 5 16 207 207.0000 2 3 207 207
5 27 132 5 16 207 207.0000 1 21 909 12
5 27 132 5 16 207 207.0000 7 13 312 406
5 27 132 5 16 207 207.0000 8 64 248 107
5 27 132 5 16 207 207.0000 6 20 315 279
5 27 132 5 16 207 207.0000 1 19 203 107
5 27 132 5 16 207 207.0000 8 80 800 314
5 27 132 5 16 207 207.0000 3 12 231 190
5 27 132 5 16 207 207.0000 6 23 303 909
6 20 315 6 20 315 279.3333 2 3 207 207
6 20 315 6 20 315 279.3333 1 21 909 12
6 20 315 6 20 315 279.3333 7 13 312 406
6 20 315 6 20 315 279.3333 8 64 248 107
6 20 315 6 20 315 279.3333 6 20 315 279
6 20 315 6 20 315 279.3333 1 19 203 107
6 20 315 6 20 315 279.3333 8 80 800 314
6 20 315 6 20 315 279.3333 3 12 231 190
6 20 315 6 20 315 279.3333 6 23 303 909
8 33 404 8 33 404 213.6667 2 3 207 207
1 19 107 1 21 500 234.6000 1 21 909 12
5 16 207 5 16 207 207.0000 1 21 909 12
5 27 132 5 16 207 207.0000 1 21 909 12
6 20 315 6 20 315 279.3333 1 21 909 12
8 33 404 8 33 404 213.6667 1 21 909 12
1 19 107 1 21 500 234.6000 7 13 312 406
5 16 207 5 16 207 207.0000 7 13 312 406
5 27 132 5 16 207 207.0000 7 13 312 406
6 20 315 6 20 315 279.3333 7 13 312 406
8 33 404 8 33 404 213.6667 7 13 312 406
1 19 107 1 21 500 234.6000 8 64 248 107
5 16 207 5 16 207 207.0000 8 64 248 107
5 27 132 5 16 207 207.0000 8 64 248 107
6 20 315 6 20 315 279.3333 8 64 248 107
8 33 404 8 33 404 213.6667 8 64 248 107
1 19 107 1 21 500 234.6000 6 20 315 279
5 16 207 5 16 207 207.0000 6 20 315 279
5 27 132 5 16 207 207.0000 6 20 315 279
6 20 315 6 20 315 279.3333 6 20 315 279
8 33 404 8 33 404 213.6667 6 20 315 279
1 19 107 1 21 500 234.6000 1 19 203 107
5 16 207 5 16 207 207.0000 1 19 203 107
5 27 132 5 16 207 207.0000 1 19 203 107
6 20 315 6 20 315 279.3333 1 19 203 107
8 33 404 8 33 404 213.6667 1 19 203 107
1 19 107 1 21 500 234.6000 8 80 800 314
5 16 207 5 16 207 207.0000 8 80 800 314
5 27 132 5 16 207 207.0000 8 80 800 314
6 20 315 6 20 315 279.3333 8 80 800 314
8 33 404 8 33 404 213.6667 8 80 800 314
1 19 107 1 21 500 234.6000 3 12 231 190
5 16 207 5 16 207 207.0000 3 12 231 190
5 27 132 5 16 207 207.0000 3 12 231 190
6 20 315 6 20 315 279.3333 3 12 231 190
8 33 404 8 33 404 213.6667 3 12 231 190
1 19 107 1 21 500 234.6000 6 23 303 909
5 16 207 5 16 207 207.0000 6 23 303 909
5 27 132 5 16 207 207.0000 6 23 303 909
6 20 315 6 20 315 279.3333 6 23 303 909
8 33 404 8 33 404 213.6667 6 23 303 909
select * from v4,v1,t2 where
(((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a);
a b min_c a b max_c avg_c a b c d
1 19 107 1 21 500 234.6000 2 3 207 207
1 19 107 1 21 500 234.6000 1 21 909 12
1 19 107 1 21 500 234.6000 7 13 312 406
1 19 107 1 21 500 234.6000 8 64 248 107
1 19 107 1 21 500 234.6000 6 20 315 279
1 19 107 1 21 500 234.6000 1 19 203 107
1 19 107 1 21 500 234.6000 8 80 800 314
1 19 107 1 21 500 234.6000 3 12 231 190
1 19 107 1 21 500 234.6000 6 23 303 909
5 16 207 5 16 207 207.0000 2 3 207 207
5 16 207 5 16 207 207.0000 1 21 909 12
5 16 207 5 16 207 207.0000 7 13 312 406
5 16 207 5 16 207 207.0000 8 64 248 107
5 16 207 5 16 207 207.0000 6 20 315 279
5 16 207 5 16 207 207.0000 1 19 203 107
5 16 207 5 16 207 207.0000 8 80 800 314
5 16 207 5 16 207 207.0000 3 12 231 190
5 16 207 5 16 207 207.0000 6 23 303 909
5 27 132 5 16 207 207.0000 2 3 207 207
5 27 132 5 16 207 207.0000 1 21 909 12
5 27 132 5 16 207 207.0000 7 13 312 406
5 27 132 5 16 207 207.0000 8 64 248 107
5 27 132 5 16 207 207.0000 6 20 315 279
5 27 132 5 16 207 207.0000 1 19 203 107
5 27 132 5 16 207 207.0000 8 80 800 314
5 27 132 5 16 207 207.0000 3 12 231 190
5 27 132 5 16 207 207.0000 6 23 303 909
6 20 315 6 20 315 279.3333 2 3 207 207
6 20 315 6 20 315 279.3333 1 21 909 12
6 20 315 6 20 315 279.3333 7 13 312 406
6 20 315 6 20 315 279.3333 8 64 248 107
6 20 315 6 20 315 279.3333 6 20 315 279
6 20 315 6 20 315 279.3333 1 19 203 107
6 20 315 6 20 315 279.3333 8 80 800 314
6 20 315 6 20 315 279.3333 3 12 231 190
6 20 315 6 20 315 279.3333 6 23 303 909
8 33 404 8 33 404 213.6667 2 3 207 207
1 19 107 1 21 500 234.6000 1 21 909 12
5 16 207 5 16 207 207.0000 1 21 909 12
5 27 132 5 16 207 207.0000 1 21 909 12
6 20 315 6 20 315 279.3333 1 21 909 12
8 33 404 8 33 404 213.6667 1 21 909 12
1 19 107 1 21 500 234.6000 7 13 312 406
5 16 207 5 16 207 207.0000 7 13 312 406
5 27 132 5 16 207 207.0000 7 13 312 406
6 20 315 6 20 315 279.3333 7 13 312 406
8 33 404 8 33 404 213.6667 7 13 312 406
1 19 107 1 21 500 234.6000 8 64 248 107
5 16 207 5 16 207 207.0000 8 64 248 107
5 27 132 5 16 207 207.0000 8 64 248 107
6 20 315 6 20 315 279.3333 8 64 248 107
8 33 404 8 33 404 213.6667 8 64 248 107
1 19 107 1 21 500 234.6000 6 20 315 279
5 16 207 5 16 207 207.0000 6 20 315 279
5 27 132 5 16 207 207.0000 6 20 315 279
6 20 315 6 20 315 279.3333 6 20 315 279
8 33 404 8 33 404 213.6667 6 20 315 279
1 19 107 1 21 500 234.6000 1 19 203 107
5 16 207 5 16 207 207.0000 1 19 203 107
5 27 132 5 16 207 207.0000 1 19 203 107
6 20 315 6 20 315 279.3333 1 19 203 107
8 33 404 8 33 404 213.6667 1 19 203 107
1 19 107 1 21 500 234.6000 8 80 800 314
5 16 207 5 16 207 207.0000 8 80 800 314
5 27 132 5 16 207 207.0000 8 80 800 314
6 20 315 6 20 315 279.3333 8 80 800 314
8 33 404 8 33 404 213.6667 8 80 800 314
1 19 107 1 21 500 234.6000 3 12 231 190
5 16 207 5 16 207 207.0000 3 12 231 190
5 27 132 5 16 207 207.0000 3 12 231 190
6 20 315 6 20 315 279.3333 3 12 231 190
8 33 404 8 33 404 213.6667 3 12 231 190
1 19 107 1 21 500 234.6000 6 23 303 909
5 16 207 5 16 207 207.0000 6 23 303 909
5 27 132 5 16 207 207.0000 6 23 303 909
6 20 315 6 20 315 279.3333 6 23 303 909
8 33 404 8 33 404 213.6667 6 23 303 909
explain select * from v4,v1,t2 where
(((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 9
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where
1 PRIMARY <derived4> ref key0 key0 5 v4.a 2 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using join buffer (flat, BNL join)
4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort
2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort
@ -7906,29 +7904,13 @@ EXPLAIN
"cost": "COST_REPLACED",
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 1,
"rows": 9,
"cost": "COST_REPLACED",
"filtered": 100
}
},
{
"block-nl-join": {
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"loops": 9,
"loops": 1,
"rows": 20,
"cost": "COST_REPLACED",
"filtered": 100,
"attached_condition": "v4.b > 10 and v4.a > 1 or v4.b < 20"
},
"buffer_type": "flat",
"buffer_size": "238",
"join_type": "BNL",
"attached_condition": "(v4.b > 10 and v4.a > 1 or v4.b < 20) and v4.a is not null",
"materialized": {
"query_block": {
@ -7990,7 +7972,7 @@ EXPLAIN
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["v4.a"],
"loops": 180,
"loops": 20,
"rows": 2,
"cost": "COST_REPLACED",
"filtered": 100,
@ -8020,6 +8002,21 @@ EXPLAIN
}
}
}
},
{
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 40,
"rows": 9,
"cost": "COST_REPLACED",
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "1Kb",
"join_type": "BNL"
}
}
]
}
@ -22669,7 +22666,7 @@ EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.012461052,
"cost": 0.010134054,
"nested_loop": [
{
"table": {
@ -22677,7 +22674,7 @@ EXPLAIN
"access_type": "ALL",
"loops": 1,
"rows": 3,
"cost": 0.012461052,
"cost": 0.010134054,
"filtered": 100,
"attached_condition": "v1.r < 'x'",
"materialized": {

100
mysql-test/main/opt_trace.result

@ -566,8 +566,8 @@ select * from v2 {
"table": "<derived2>",
"table_scan": {
"rows": 2,
"read_cost": 0.012350033,
"read_and_compare_cost": 0.012418701
"read_cost": 0.010020701,
"read_and_compare_cost": 0.010089369
}
}
]
@ -589,7 +589,7 @@ select * from v2 {
"rows": 2,
"rows_after_filter": 2,
"rows_out": 2,
"cost": 0.012418701,
"cost": 0.010089369,
"index_only": false,
"chosen": true
}
@ -598,7 +598,7 @@ select * from v2 {
"type": "scan",
"rows_read": 2,
"rows_out": 2,
"cost": 0.012418701,
"cost": 0.010089369,
"uses_join_buffering": false
}
}
@ -609,14 +609,14 @@ select * from v2 {
"plan_prefix": "",
"table": "<derived2>",
"rows_for_plan": 2,
"cost_for_plan": 0.012418701
"cost_for_plan": 0.010089369
}
]
},
{
"best_join_order": ["<derived2>"],
"rows": 2,
"cost": 0.012418701
"cost": 0.010089369
},
{
"attaching_conditions_to_tables": {
@ -954,8 +954,8 @@ explain select * from v1 {
"table": "<derived2>",
"table_scan": {
"rows": 10,
"read_cost": 0.012414166,
"read_and_compare_cost": 0.012757506
"read_cost": 0.010103506,
"read_and_compare_cost": 0.010446846
}
}
]
@ -977,7 +977,7 @@ explain select * from v1 {
"rows": 10,
"rows_after_filter": 10,
"rows_out": 10,
"cost": 0.012757506,
"cost": 0.010446846,
"index_only": false,
"chosen": true
}
@ -986,7 +986,7 @@ explain select * from v1 {
"type": "scan",
"rows_read": 10,
"rows_out": 10,
"cost": 0.012757506,
"cost": 0.010446846,
"uses_join_buffering": false
}
}
@ -997,14 +997,14 @@ explain select * from v1 {
"plan_prefix": "",
"table": "<derived2>",
"rows_for_plan": 10,
"cost_for_plan": 0.012757506
"cost_for_plan": 0.010446846
}
]
},
{
"best_join_order": ["<derived2>"],
"rows": 10,
"cost": 0.012757506
"cost": 0.010446846
},
{
"attaching_conditions_to_tables": {
@ -4974,8 +4974,8 @@ explain select * from (select rand() from t1)q {
"table": "<derived2>",
"table_scan": {
"rows": 3,
"read_cost": 0.01235805,
"read_and_compare_cost": 0.012461052
"read_cost": 0.010031052,
"read_and_compare_cost": 0.010134054
}
}
]
@ -4997,7 +4997,7 @@ explain select * from (select rand() from t1)q {
"rows": 3,
"rows_after_filter": 3,
"rows_out": 3,
"cost": 0.012461052,
"cost": 0.010134054,
"index_only": false,
"chosen": true
}
@ -5006,7 +5006,7 @@ explain select * from (select rand() from t1)q {
"type": "scan",
"rows_read": 3,
"rows_out": 3,
"cost": 0.012461052,
"cost": 0.010134054,
"uses_join_buffering": false
}
}
@ -5017,14 +5017,14 @@ explain select * from (select rand() from t1)q {
"plan_prefix": "",
"table": "<derived2>",
"rows_for_plan": 3,
"cost_for_plan": 0.012461052
"cost_for_plan": 0.010134054
}
]
},
{
"best_join_order": ["<derived2>"],
"rows": 3,
"cost": 0.012461052
"cost": 0.010134054
},
{
"attaching_conditions_to_tables": {
@ -11900,8 +11900,8 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
"table": "<derived2>",
"table_scan": {
"rows": 2,
"read_cost": 0.012350033,
"read_and_compare_cost": 0.012418701
"read_cost": 0.010020701,
"read_and_compare_cost": 0.010089369
}
}
]
@ -11949,7 +11949,7 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
"rows": 2,
"rows_after_filter": 2,
"rows_out": 2,
"cost": 0.012418701,
"cost": 0.010089369,
"index_only": false,
"chosen": true
}
@ -11958,7 +11958,7 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
"type": "scan",
"rows_read": 2,
"rows_out": 2,
"cost": 0.012418701,
"cost": 0.010089369,
"uses_join_buffering": false
}
}
@ -11986,8 +11986,8 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
"rows": 2,
"rows_after_filter": 2,
"rows_out": 2,
"cost": 0.012911897,
"cost_without_join_buffer": 0.024837402,
"cost": 0.010582565,
"cost_without_join_buffer": 0.020178738,
"index_only": false,
"chosen": true
}
@ -11996,7 +11996,7 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
"type": "scan",
"rows_read": 2,
"rows_out": 2,
"cost": 0.012911897,
"cost": 0.010582565,
"uses_join_buffering": true
}
}
@ -12007,7 +12007,7 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
"plan_prefix": "t",
"table": "<derived2>",
"rows_for_plan": 4,
"cost_for_plan": 0.023260307
"cost_for_plan": 0.020930975
}
]
},
@ -12015,15 +12015,57 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
"plan_prefix": "",
"table": "<derived2>",
"rows_for_plan": 2,
"cost_for_plan": 0.012418701,
"pruned_by_heuristic": true
"cost_for_plan": 0.010089369,
"rest_of_plan": [
{
"plan_prefix": "<derived2>",
"get_costs_for_tables": [
{
"best_access_path": {
"table": "t",
"plan_details": {
"record_count": 2
},
"considered_access_paths": [
{
"access_type": "scan_with_join_cache",
"rows": 2,
"rows_after_filter": 2,
"rows_out": 2,
"cost": 0.010841606,
"cost_without_join_buffer": 0.02069682,
"index_only": false,
"chosen": true
}
],
"chosen_access_method": {
"type": "scan",
"rows_read": 2,
"rows_out": 2,
"cost": 0.010841606,
"uses_join_buffering": true
}
}
}
]
},
{
"plan_prefix": "<derived2>",
"table": "t",
"rows_for_plan": 4,
"cost_for_plan": 0.020930975,
"pruned_by_cost": true,
"current_cost": 0.020930975,
"best_cost": 0.020930975
}
]
}
]
},
{
"best_join_order": ["t", "<derived2>"],
"rows": 4,
"cost": 0.023260307
"cost": 0.020930975
},
{
"substitute_best_equal": {

6
mysql-test/main/opt_tvc.result

@ -530,11 +530,11 @@ a b
4 yq
explain extended select * from t3 where a in (1,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL idx NULL NULL NULL 28 100.00 Using where
1 PRIMARY <derived3> eq_ref distinct_key distinct_key 4 test.t3.a 1 100.00
1 PRIMARY <derived3> ALL distinct_key NULL NULL NULL 2 100.00
1 PRIMARY t3 ref idx idx 5 tvc_0._col_1 3 100.00
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from (values (1),(4)) `tvc_0` join `test`.`t3` where `tvc_0`.`_col_1` = `test`.`t3`.`a`
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from (values (1),(4)) `tvc_0` join `test`.`t3` where `test`.`t3`.`a` = `tvc_0`.`_col_1`
# use vectors in IN predeicate
set @@in_predicate_conversion_threshold= 4;
select * from t1 where (a,b) in ((1,2),(3,4));

2
mysql-test/main/optimizer_costs.result

@ -69,7 +69,7 @@ OPTIMIZER_KEY_NEXT_FIND_COST 0.000000
OPTIMIZER_DISK_READ_RATIO 0.000000
OPTIMIZER_ROW_COPY_COST 0.002334
OPTIMIZER_ROW_LOOKUP_COST 0.000000
OPTIMIZER_ROW_NEXT_FIND_COST 0.000000
OPTIMIZER_ROW_NEXT_FIND_COST 0.008017
OPTIMIZER_ROWID_COMPARE_COST 0.002653
OPTIMIZER_ROWID_COPY_COST 0.002653
show variables like "optimizer%cost";

6
mysql-test/main/subselect_sj.result

@ -2260,10 +2260,10 @@ alias1.c IN (SELECT SQ3_alias1.b
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
LIMIT 100;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias2 ALL NULL NULL NULL NULL 20
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20
1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Start temporary
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Start temporary
1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary
2 DERIVED t2 ALL NULL NULL NULL NULL 20
create table t3 as

8
mysql-test/main/subselect_sj_jcl6.result

@ -2266,10 +2266,10 @@ alias1.c IN (SELECT SQ3_alias1.b
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
LIMIT 100;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias2 ALL NULL NULL NULL NULL 20
1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Start temporary; Using join buffer (incremental, BNL join)
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20
1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (incremental, BNL join)
1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Start temporary; Using join buffer (incremental, BNL join)
1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary; Using join buffer (incremental, BNL join)
2 DERIVED t2 ALL NULL NULL NULL NULL 20
create table t3 as

52
sql/sql_select.cc

@ -16598,24 +16598,62 @@ void JOIN_TAB::estimate_scan_time()
}
else
{
bool using_heap= 0;
TABLE_SHARE *share= table->s;
handler *tmp_file= file;
records= table->stat_records();
if (share->db_type() == heap_hton)
{
/* Check that the rows will fit into the heap table */
ha_rows max_rows;
max_rows= (ha_rows) (MY_MIN(thd->variables.tmp_memory_table_size,
thd->variables.max_heap_table_size) /
MY_ALIGN(share->reclength, sizeof(char*)));
if (records <= max_rows)
{
/* The rows will fit into the heap table */
using_heap= 1;
}
else if (likely((tmp_file= get_new_handler(share, &table->mem_root,
TMP_ENGINE_HTON))))
{
tmp_file->costs= &tmp_table_optimizer_costs;
}
else
tmp_file= file; // Fallback for OOM
}
/*
The following is same as calling
TABLE_SHARE::update_optimizer_costs, but without locks
*/
if (table->s->db_type() == heap_hton)
memcpy(&table->s->optimizer_costs, &heap_optimizer_costs,
if (using_heap)
memcpy(&share->optimizer_costs, &heap_optimizer_costs,
sizeof(heap_optimizer_costs));
else
memcpy(&table->s->optimizer_costs, &tmp_table_optimizer_costs,
{
memcpy(&share->optimizer_costs, &tmp_table_optimizer_costs,
sizeof(tmp_table_optimizer_costs));
file->set_optimizer_costs(thd);
/* Set data_file_length in case of Aria tmp table */
tmp_file->stats.data_file_length= share->reclength * records;
}
table->s->optimizer_costs_inited=1;
/* Add current WHERE and SCAN SETUP cost to tmp file */
tmp_file->set_optimizer_costs(thd);
records= table->stat_records();
DBUG_ASSERT(table->opt_range_condition_rows == records);
cost->row_cost= table->file->ha_scan_time(MY_MAX(records, 1000));
read_time= file->cost(cost->row_cost);
cost->row_cost= tmp_file->ha_scan_time(records);
tmp_file->stats.data_file_length= 0;
read_time= tmp_file->cost(cost->row_cost);
row_copy_cost= table->s->optimizer_costs.row_copy_cost;
if (file != tmp_file)
{
delete tmp_file;
file->set_optimizer_costs(thd);
}
}
found_records= records;

6
storage/heap/ha_heap.cc

@ -54,7 +54,7 @@ static void heap_update_optimizer_costs(OPTIMIZER_COSTS *costs)
costs->key_copy_cost= 0; // Set in keyread_time()
costs->row_copy_cost= 2.334e-06; // This is small as its just a memcpy
costs->row_lookup_cost= 0; // Direct pointer
costs->row_next_find_cost= 0;
costs->row_next_find_cost= HEAP_ROW_NEXT_FIND_COST;
costs->key_lookup_cost= 0;
costs->key_next_find_cost= 0;
costs->index_block_copy_cost= 0;
@ -268,7 +268,9 @@ IO_AND_CPU_COST ha_heap::keyread_time(uint index, ulong ranges, ha_rows rows,
IO_AND_CPU_COST ha_heap::scan_time()
{
return {0, (double) (stats.records+stats.deleted) * HEAP_ROW_NEXT_FIND_COST };
/* The caller ha_scan_time() handles stats.records */
return {0, (double) stats.deleted * HEAP_ROW_NEXT_FIND_COST };
}

Loading…
Cancel
Save