Skip to content

Commit 1c75ad6

Browse files
committed
MDEV-19834 Selectivity of an equality condition discounted twice
When discounting selectivity of ref access, don't discount the selectivity we've already discounted for range access. The 10.1 version of the fix. Will need to adjust condition filtering test results in 10.4
1 parent 588e679 commit 1c75ad6

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

mysql-test/r/selectivity.result

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,3 +1635,37 @@ set @@use_stat_tables= @save_use_stat_tables;
16351635
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
16361636
drop table t1;
16371637
drop function f1;
1638+
#
1639+
# MDEV-19834 Selectivity of an equality condition discounted twice
1640+
#
1641+
set @@optimizer_use_condition_selectivity=4;
1642+
set @@use_stat_tables='preferably';
1643+
create table t1 (a int, b int, key (b), key (a));
1644+
insert into t1
1645+
select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
1646+
analyze table t1 ;
1647+
Table Op Msg_type Msg_text
1648+
test.t1 analyze status Engine-independent statistics collected
1649+
test.t1 analyze status Table is already up to date
1650+
# Check what info the optimizer has about selectivities
1651+
explain extended select * from t1 use index () where a in (17,51,5);
1652+
id select_type table type possible_keys key key_len ref rows filtered Extra
1653+
1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.97 Using where
1654+
Warnings:
1655+
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where (`test`.`t1`.`a` in (17,51,5))
1656+
explain extended select * from t1 use index () where b=2;
1657+
id select_type table type possible_keys key key_len ref rows filtered Extra
1658+
1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 4.76 Using where
1659+
Warnings:
1660+
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where (`test`.`t1`.`b` = 2)
1661+
# Now, the equality is used for ref access, while the range condition
1662+
# gives selectivity data
1663+
explain extended select * from t1 where a in (17,51,5) and b=2;
1664+
id select_type table type possible_keys key key_len ref rows filtered Extra
1665+
1 SIMPLE t1 ref b,a b 5 const 58 2.90 Using where
1666+
Warnings:
1667+
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 2) and (`test`.`t1`.`a` in (17,51,5)))
1668+
drop table t1;
1669+
set use_stat_tables= @save_use_stat_tables;
1670+
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
1671+
# End of 10.1 tests

mysql-test/t/selectivity.test

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
--source include/have_stat_tables.inc
2+
--source include/have_sequence.inc
23

34
--disable_warnings
45
drop table if exists t0,t1,t2,t3;
@@ -1102,3 +1103,26 @@ set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectiv
11021103
drop table t1;
11031104
drop function f1;
11041105

1106+
--echo #
1107+
--echo # MDEV-19834 Selectivity of an equality condition discounted twice
1108+
--echo #
1109+
set @@optimizer_use_condition_selectivity=4;
1110+
set @@use_stat_tables='preferably';
1111+
create table t1 (a int, b int, key (b), key (a));
1112+
insert into t1
1113+
select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
1114+
analyze table t1 ;
1115+
1116+
--echo # Check what info the optimizer has about selectivities
1117+
explain extended select * from t1 use index () where a in (17,51,5);
1118+
explain extended select * from t1 use index () where b=2;
1119+
1120+
--echo # Now, the equality is used for ref access, while the range condition
1121+
--echo # gives selectivity data
1122+
explain extended select * from t1 where a in (17,51,5) and b=2;
1123+
drop table t1;
1124+
1125+
set use_stat_tables= @save_use_stat_tables;
1126+
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
1127+
--echo # End of 10.1 tests
1128+

sql/sql_select.cc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7618,6 +7618,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
76187618
KEYUSE *keyuse= pos->key;
76197619
KEYUSE *prev_ref_keyuse= keyuse;
76207620
uint key= keyuse->key;
7621+
bool used_range_selectivity= false;
76217622

76227623
/*
76237624
Check if we have a prefix of key=const that matches a quick select.
@@ -7643,6 +7644,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
76437644
keyparts++;
76447645
}
76457646
sel /= (double)table->quick_rows[key] / (double) table->stat_records();
7647+
used_range_selectivity= true;
76467648
}
76477649
}
76487650

@@ -7678,13 +7680,14 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
76787680
if (keyparts > keyuse->keypart)
76797681
{
76807682
/* Ok this is the keyuse that will be used for ref access */
7681-
uint fldno;
7682-
if (is_hash_join_key_no(key))
7683-
fldno= keyuse->keypart;
7684-
else
7685-
fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1;
7686-
if (keyuse->val->const_item())
7683+
if (!used_range_selectivity && keyuse->val->const_item())
76877684
{
7685+
uint fldno;
7686+
if (is_hash_join_key_no(key))
7687+
fldno= keyuse->keypart;
7688+
else
7689+
fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1;
7690+
76887691
if (table->field[fldno]->cond_selectivity > 0)
76897692
{
76907693
sel /= table->field[fldno]->cond_selectivity;

0 commit comments

Comments
 (0)