mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-31356: Range cost calculations does not take into account join_buffer
This patch also fixes MDEV-31391 Assertion `((best.records_out) == 0.0 ... failed Cost changes caused by this change: - range queries with join buffer now have a notable smaller cost. - range ranges are bit more expensive as the MULTI_RANGE_COST is now properly applied to it in all cases (this extra cost is equal to a key lookup). - table scan cost is slight smaller as we now assume data is cached in the engine after the first scan pass. (We did this before for range scans and other access methods). - partition tables had wrong values for max_row_blocks and max_index_blocks. Correcting this, causes range access on partitioned tables to have slightly higher cost because of the increased estimated IO. - Using first match + join buffer caused 'filtered' to be calcualted wrong. (Only affected EXPLAIN, not query costs). - Added cost_without_join_buffer to optimizer_trace. - check_quick_select() adjusted the number of rows according to persistent statistics, but did not adjust cost. Now fixed. The big change in the patch are: - In best_access_path(), where we now are using storing the cost in 'ALL_READ_COST cost' and only converting it to a double at the end. This allows us to more exactly calculate the effect of the join_cache. - In JOIN_TAB::estimate_scan_time(), store the cost also in a ALL_READ_COST object. One of effect if this change is that when joining very small tables: t1 some_access_method t2 range t3 ALL Use join buffer This is swiched to t1 some_access_method t3 ALL t2 range use join buffer Both plans has the same cost, but as table scan in this case has less cost than rang, the table scan will be considered first and thus have precidence. Test case changes: - optimizer_trace - Addition of cost_without_join_buffer - subselect_mat_cost_bugs - Small tables and scan versus range - range & range_mrr_icp - Range + join_cache is faster than ref - optimizer_trace - cost_without_join_buffer, smaller scan cost, range setup cost. - mrr - range+join_buffer used as smaller cost
This commit is contained in:
@ -2831,8 +2831,8 @@ alter table t2 drop index idx1, drop index idx2, add index idx3(d,e);
|
||||
explain select * from t1,t2
|
||||
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 range idx3 idx3 10 NULL 5 Using index condition; Using where
|
||||
1 SIMPLE t1 ref idx idx 5 test.t2.d 11
|
||||
1 SIMPLE t1 range idx idx 5 NULL 15 Using index condition
|
||||
1 SIMPLE t2 range idx3 idx3 10 NULL 5 Using where; Using join buffer (flat, BNL join)
|
||||
explain format=json select * from t1,t2
|
||||
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||
EXPLAIN
|
||||
@ -2841,35 +2841,40 @@ EXPLAIN
|
||||
"select_id": 1,
|
||||
"cost": "COST_REPLACED",
|
||||
"nested_loop": [
|
||||
{
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "range",
|
||||
"possible_keys": ["idx3"],
|
||||
"key": "idx3",
|
||||
"key_length": "10",
|
||||
"used_key_parts": ["d", "e"],
|
||||
"loops": 1,
|
||||
"rows": 5,
|
||||
"cost": "COST_REPLACED",
|
||||
"filtered": 100,
|
||||
"index_condition": "t2.d is not null",
|
||||
"attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ref",
|
||||
"access_type": "range",
|
||||
"possible_keys": ["idx"],
|
||||
"key": "idx",
|
||||
"key_length": "5",
|
||||
"used_key_parts": ["a"],
|
||||
"ref": ["test.t2.d"],
|
||||
"loops": 5,
|
||||
"rows": 11,
|
||||
"loops": 1,
|
||||
"rows": 15,
|
||||
"cost": "COST_REPLACED",
|
||||
"filtered": 100
|
||||
"filtered": 100,
|
||||
"index_condition": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"block-nl-join": {
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "range",
|
||||
"possible_keys": ["idx3"],
|
||||
"key": "idx3",
|
||||
"key_length": "10",
|
||||
"used_key_parts": ["d", "e"],
|
||||
"loops": 15,
|
||||
"rows": 5,
|
||||
"cost": "COST_REPLACED",
|
||||
"filtered": 60,
|
||||
"attached_condition": "octet_length(t2.f) = 1"
|
||||
},
|
||||
"buffer_type": "flat",
|
||||
"buffer_size": "461",
|
||||
"join_type": "BNL",
|
||||
"attached_condition": "t2.d = t1.a and (t1.a,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8)))"
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -2878,14 +2883,14 @@ EXPLAIN
|
||||
select * from t1,t2
|
||||
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||
a b c d e f
|
||||
7 7 xxxyy 7 7 h
|
||||
7 7 xxxya 7 7 h
|
||||
7 7 xxxya 7 7 h
|
||||
7 7 xxxyy 7 7 h
|
||||
7 7 xxxya 7 7 h
|
||||
7 8 xxxxx 7 7 h
|
||||
7 7 xxxyy 7 7 h
|
||||
7 8 xxxxa 7 7 h
|
||||
7 8 xxxxa 7 7 h
|
||||
7 8 xxxxx 7 7 h
|
||||
7 8 xxxxa 7 7 h
|
||||
7 8 xxxxx 7 7 h
|
||||
# join order: (t1,t2) with ref access of t2
|
||||
# range access to t1 by 1-component keys for index idx
|
||||
explain select * from t1,t2
|
||||
|
Reference in New Issue
Block a user