Skip to content

Commit 587c720

Browse files
committed
Fixed bug mdev-7316.
The function table_cond_selectivity() should take into account that condition selectivity for some fields can be set to 0.
1 parent 826d7c6 commit 587c720

File tree

4 files changed

+104
-2
lines changed

4 files changed

+104
-2
lines changed

mysql-test/r/selectivity.result

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,4 +1409,40 @@ Note 1003 select `test`.`a`.`a` AS `a`,`test`.`a`.`b` AS `b`,`test`.`b`.`a` AS `
14091409
set histogram_size=@save_histogram_size;
14101410
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
14111411
drop table t0,t1,t2;
1412+
#
1413+
# Bug mdev-7316: a conjunct in WHERE with selectivity == 0
1414+
#
1415+
CREATE TABLE t1 (a varchar(16), b int, PRIMARY KEY(a), KEY(b)) ENGINE=INNODB;
1416+
Warnings:
1417+
Warning 1286 Unknown storage engine 'INNODB'
1418+
Warning 1266 Using storage engine MyISAM for table 't1'
1419+
INSERT INTO t1 VALUES
1420+
('USAChinese',10), ('USAEnglish',20), ('USAFrench',30);
1421+
CREATE TABLE t2 (i int) ENGINE=INNODB;
1422+
Warnings:
1423+
Warning 1286 Unknown storage engine 'INNODB'
1424+
Warning 1266 Using storage engine MyISAM for table 't2'
1425+
INSERT INTO t2 VALUES
1426+
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(1),(2),(3),(4);
1427+
ANALYZE TABLE t1, t2;
1428+
Table Op Msg_type Msg_text
1429+
test.t1 analyze status Engine-independent statistics collected
1430+
test.t1 analyze status OK
1431+
test.t2 analyze status Engine-independent statistics collected
1432+
test.t2 analyze status OK
1433+
set use_stat_tables='preferably';
1434+
set optimizer_use_condition_selectivity=3;
1435+
EXPLAIN EXTENDED
1436+
SELECT * FROM t1, t2
1437+
WHERE a <> 'USARussian' AND b IS NULL;
1438+
id select_type table type possible_keys key key_len ref rows filtered Extra
1439+
1 SIMPLE t1 ref PRIMARY,b b 5 const 1 100.00 Using index condition; Using where
1440+
1 SIMPLE t2 ALL NULL NULL NULL NULL 14 100.00 Using join buffer (flat, BNL join)
1441+
Warnings:
1442+
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`i` AS `i` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a` <> 'USARussian') and isnull(`test`.`t1`.`b`))
1443+
SELECT * FROM t1, t2
1444+
WHERE a <> 'USARussian' AND b IS NULL;
1445+
a b i
1446+
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
1447+
DROP TABLE t1,t2;
14121448
set use_stat_tables=@save_use_stat_tables;

mysql-test/r/selectivity_innodb.result

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,36 @@ Note 1003 select `test`.`a`.`a` AS `a`,`test`.`a`.`b` AS `b`,`test`.`b`.`a` AS `
14191419
set histogram_size=@save_histogram_size;
14201420
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
14211421
drop table t0,t1,t2;
1422+
#
1423+
# Bug mdev-7316: a conjunct in WHERE with selectivity == 0
1424+
#
1425+
CREATE TABLE t1 (a varchar(16), b int, PRIMARY KEY(a), KEY(b)) ENGINE=INNODB;
1426+
INSERT INTO t1 VALUES
1427+
('USAChinese',10), ('USAEnglish',20), ('USAFrench',30);
1428+
CREATE TABLE t2 (i int) ENGINE=INNODB;
1429+
INSERT INTO t2 VALUES
1430+
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(1),(2),(3),(4);
1431+
ANALYZE TABLE t1, t2;
1432+
Table Op Msg_type Msg_text
1433+
test.t1 analyze status Engine-independent statistics collected
1434+
test.t1 analyze status OK
1435+
test.t2 analyze status Engine-independent statistics collected
1436+
test.t2 analyze status OK
1437+
set use_stat_tables='preferably';
1438+
set optimizer_use_condition_selectivity=3;
1439+
EXPLAIN EXTENDED
1440+
SELECT * FROM t1, t2
1441+
WHERE a <> 'USARussian' AND b IS NULL;
1442+
id select_type table type possible_keys key key_len ref rows filtered Extra
1443+
1 SIMPLE t1 ref PRIMARY,b b 5 const 2 66.67 Using where; Using index
1444+
1 SIMPLE t2 ALL NULL NULL NULL NULL 14 100.00 Using join buffer (flat, BNL join)
1445+
Warnings:
1446+
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`i` AS `i` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a` <> 'USARussian') and isnull(`test`.`t1`.`b`))
1447+
SELECT * FROM t1, t2
1448+
WHERE a <> 'USARussian' AND b IS NULL;
1449+
a b i
1450+
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
1451+
DROP TABLE t1,t2;
14221452
set use_stat_tables=@save_use_stat_tables;
14231453
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
14241454
set @tmp_ust= @@use_stat_tables;

mysql-test/t/selectivity.test

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,5 +942,34 @@ set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivit
942942

943943
drop table t0,t1,t2;
944944

945+
--echo #
946+
--echo # Bug mdev-7316: a conjunct in WHERE with selectivity == 0
947+
--echo #
948+
949+
CREATE TABLE t1 (a varchar(16), b int, PRIMARY KEY(a), KEY(b)) ENGINE=INNODB;
950+
INSERT INTO t1 VALUES
951+
('USAChinese',10), ('USAEnglish',20), ('USAFrench',30);
952+
953+
CREATE TABLE t2 (i int) ENGINE=INNODB;
954+
INSERT INTO t2 VALUES
955+
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(1),(2),(3),(4);
956+
957+
ANALYZE TABLE t1, t2;
958+
959+
set use_stat_tables='preferably';
960+
set optimizer_use_condition_selectivity=3;
961+
962+
EXPLAIN EXTENDED
963+
SELECT * FROM t1, t2
964+
WHERE a <> 'USARussian' AND b IS NULL;
965+
966+
SELECT * FROM t1, t2
967+
WHERE a <> 'USARussian' AND b IS NULL;
968+
969+
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
970+
971+
DROP TABLE t1,t2;
972+
973+
945974
set use_stat_tables=@save_use_stat_tables;
946975

sql/sql_select.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7449,8 +7449,12 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
74497449
else
74507450
fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1;
74517451
if (keyuse->val->const_item())
7452-
{
7453-
sel /= table->field[fldno]->cond_selectivity;
7452+
{
7453+
if (table->field[fldno]->cond_selectivity > 0)
7454+
{
7455+
sel /= table->field[fldno]->cond_selectivity;
7456+
set_if_smaller(sel, 1.0);
7457+
}
74547458
/*
74557459
TODO: we could do better here:
74567460
1. cond_selectivity might be =1 (the default) because quick
@@ -7504,7 +7508,10 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
75047508
if (!(next_field->table->map & rem_tables) && next_field->table != table)
75057509
{
75067510
if (field->cond_selectivity > 0)
7511+
{
75077512
sel/= field->cond_selectivity;
7513+
set_if_smaller(sel, 1.0);
7514+
}
75087515
break;
75097516
}
75107517
}

0 commit comments

Comments
 (0)