Skip to content

Commit aa5ee24

Browse files
MDEV-37723: TPROC-H Query4 much slower in 11.4 than in 10.11
(Patch provided by Monty, Testcase by Rex Johnston) get_tmp_table_costs() computes the cost of using a temporary (work table) for certain cases, including semi-join subquery materialization. The computed cost value was very low, it used this formula: key_lookup_cost * (disk_read_ratio= 0.02) Use the correct formula: key_lookup_cost // Index lookup is always done + disk_read_cost * disk_read_ratio disk_read_cost is incurred when the lookup has to go to disk. We assume this doesn't occur for every lookup. It happens only with disk_read_ratio= 0.02 frequency.
1 parent 257f4b3 commit aa5ee24

File tree

5 files changed

+122
-5
lines changed

5 files changed

+122
-5
lines changed

mysql-test/main/costs.result

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,83 @@ id select_type table type possible_keys key key_len ref rows Extra
124124
1 SIMPLE t1 range l_suppkey l_suppkey 10 NULL 1 Using where; Using index
125125
drop table t1;
126126
set global InnoDB.optimizer_disk_read_ratio=@save;
127+
#
128+
# MDEV-37723 In MDEV-36861, analyze Q4
129+
# Alter disk based tmp table lookup cost formula
130+
#
131+
create table t1 (a int primary key,
132+
b date, c char(15),
133+
d blob,
134+
key t1_ix1 (b)) ENGINE= InnoDB;
135+
create table t2 (e int not null,
136+
f int not null,
137+
g date, h date,
138+
primary key (e, f)) ENGINE= InnoDB;
139+
insert into t1 select seq, date('1993-06-01') + interval seq second,
140+
chr(65+mod(seq, 4)), NULL from seq_1_to_7000;
141+
insert into t2 select a.seq, b.seq, date('1993-06-01') + interval b.seq day,
142+
if (mod(a.seq,2), date('1993-06-01') + interval b.seq+1 day,
143+
date('1993-06-01') - interval b.seq-1 day)
144+
from seq_1_to_7000 a, seq_1_to_3 b;
145+
analyze table t1, t2;
146+
Table Op Msg_type Msg_text
147+
test.t1 analyze status Engine-independent statistics collected
148+
test.t1 analyze Warning Engine-independent statistics are not collected for column 'd'
149+
test.t1 analyze status OK
150+
test.t2 analyze status Engine-independent statistics collected
151+
test.t2 analyze status OK
152+
set @@max_heap_table_size=16384;
153+
explain format=json select c, count(*) as dc
154+
from t1
155+
where b >= date '1993-06-01'
156+
and b < date '1993-06-01' + interval '3' month
157+
and exists
158+
(
159+
select * from t2 where e = a and g < h
160+
)
161+
group by c
162+
order by c;
163+
EXPLAIN
164+
{
165+
"query_block": {
166+
"select_id": 1,
167+
"cost": 14.87747484,
168+
"filesort": {
169+
"sort_key": "t1.c",
170+
"temporary_table": {
171+
"nested_loop": [
172+
{
173+
"table": {
174+
"table_name": "t1",
175+
"access_type": "ALL",
176+
"possible_keys": ["PRIMARY", "t1_ix1"],
177+
"loops": 1,
178+
"rows": 7000,
179+
"cost": 1.1689508,
180+
"filtered": 99.7142868,
181+
"attached_condition": "t1.b >= DATE'1993-06-01' and t1.b < <cache>(DATE'1993-06-01' + interval '3' month)"
182+
}
183+
},
184+
{
185+
"table": {
186+
"table_name": "t2",
187+
"access_type": "ref",
188+
"possible_keys": ["PRIMARY"],
189+
"key": "PRIMARY",
190+
"key_length": "4",
191+
"used_key_parts": ["e"],
192+
"ref": ["test.t1.a"],
193+
"loops": 6980,
194+
"rows": 3,
195+
"cost": 9.087641,
196+
"filtered": 33.33333206,
197+
"attached_condition": "t2.g < t2.h",
198+
"first_match": "t1"
199+
}
200+
}
201+
]
202+
}
203+
}
204+
}
205+
}
206+
drop table t1, t2;

mysql-test/main/costs.test

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,38 @@ explain select count(*) from test.t1 force index (l_suppkey) where l_suppkey >=
114114
drop table t1;
115115

116116
set global InnoDB.optimizer_disk_read_ratio=@save;
117+
118+
--echo #
119+
--echo # MDEV-37723 In MDEV-36861, analyze Q4
120+
--echo # Alter disk based tmp table lookup cost formula
121+
--echo #
122+
123+
create table t1 (a int primary key,
124+
b date, c char(15),
125+
d blob,
126+
key t1_ix1 (b)) ENGINE= InnoDB;
127+
create table t2 (e int not null,
128+
f int not null,
129+
g date, h date,
130+
primary key (e, f)) ENGINE= InnoDB;
131+
--disable_warnings
132+
insert into t1 select seq, date('1993-06-01') + interval seq second,
133+
chr(65+mod(seq, 4)), NULL from seq_1_to_7000;
134+
insert into t2 select a.seq, b.seq, date('1993-06-01') + interval b.seq day,
135+
if (mod(a.seq,2), date('1993-06-01') + interval b.seq+1 day,
136+
date('1993-06-01') - interval b.seq-1 day)
137+
from seq_1_to_7000 a, seq_1_to_3 b;
138+
analyze table t1, t2;
139+
set @@max_heap_table_size=16384;
140+
explain format=json select c, count(*) as dc
141+
from t1
142+
where b >= date '1993-06-01'
143+
and b < date '1993-06-01' + interval '3' month
144+
and exists
145+
(
146+
select * from t2 where e = a and g < h
147+
)
148+
group by c
149+
order by c;
150+
151+
drop table t1, t2;

mysql-test/main/opt_trace.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12172,8 +12172,8 @@ JS
1217212172
"org_cost": 1.159965,
1217312173
"postjoin_cost": 4.020888502,
1217412174
"one_splitting_cost": 5.180853502,
12175-
"unsplit_postjoin_cost": 32.78652054,
12176-
"unsplit_cost": 148.7830205,
12175+
"unsplit_postjoin_cost": 159.1588125,
12176+
"unsplit_cost": 275.1553125,
1217712177
"rows": 100,
1217812178
"refills": 5,
1217912179
"total_splitting_cost": 25.90426751,

mysql-test/main/subselect3.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,9 +1167,9 @@ set @@optimizer_switch='firstmatch=off,materialization=off';
11671167
set @@max_heap_table_size= 16384;
11681168
explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
11691169
id select_type table type possible_keys key key_len ref rows Extra
1170-
1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary
1171-
1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
1170+
1 PRIMARY A ALL NULL NULL NULL NULL 10
11721171
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
1172+
1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary; Using join buffer (flat, BNL join)
11731173
1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
11741174
1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (flat, BNL join)
11751175
flush status;

sql/opt_subselect.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2779,12 +2779,14 @@ get_tmp_table_costs(THD *thd, double row_count, uint row_size, bool blobs_used,
27792779
tmp_table_optimizer_costs.row_copy_cost :
27802780
0);
27812781
/* Disk based table */
2782-
cost.lookup= ((tmp_table_optimizer_costs.key_lookup_cost *
2782+
cost.lookup= ((tmp_table_optimizer_costs.key_lookup_cost +
2783+
tmp_table_optimizer_costs.disk_read_cost *
27832784
tmp_table_optimizer_costs.disk_read_ratio) +
27842785
row_copy_cost);
27852786
cost.write= cost.lookup;
27862787
cost.create= DISK_TEMPTABLE_CREATE_COST;
27872788
cost.block_size= DISK_TEMPTABLE_BLOCK_SIZE;
2789+
/* The following costs are only used for table scans */
27882790
cost.avg_io_cost= tmp_table_optimizer_costs.disk_read_cost;
27892791
cost.cache_hit_ratio= tmp_table_optimizer_costs.disk_read_ratio;
27902792
}

0 commit comments

Comments
 (0)