Fixed bug mdev-4363.
When calculating the selectivity of a range in the function get_column_range_cardinality a check whether NULL values are included into into the range must be done.
This commit is contained in:
parent
10f0530b22
commit
e3bf08d4b1
@ -882,7 +882,7 @@ Table Op Msg_type Msg_text
|
|||||||
test.t1 analyze status OK
|
test.t1 analyze status OK
|
||||||
test.t2 analyze status OK
|
test.t2 analyze status OK
|
||||||
FLUSH TABLES;
|
FLUSH TABLES;
|
||||||
SET optimizer_use_condition_selectivity=3;
|
set optimizer_use_condition_selectivity=3;
|
||||||
EXPLAIN EXTENDED
|
EXPLAIN EXTENDED
|
||||||
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
|
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
@ -895,4 +895,44 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1`
|
|||||||
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
#
|
||||||
|
# Bug mdev-4363: selectivity of the condition a IS NULL OR IS NOT NULL
|
||||||
|
# with optimizer_use_condition_selectivity=3
|
||||||
|
#
|
||||||
|
set use_stat_tables = PREFERABLY;
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1),(7),(4),(7),(NULL),(2),(NULL),(4),(NULL),(NULL),(1),(3),(8),(8);
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status OK
|
||||||
|
FLUSH TABLE t1;
|
||||||
|
set optimizer_use_condition_selectivity=3;
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 28.57 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where isnull(`test`.`t1`.`a`)
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NOT NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 71.43 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` is not null)
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL OR a IS NOT NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (isnull(`test`.`t1`.`a`) or (`test`.`t1`.`a` is not null))
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL OR a < 5;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 69.39 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (isnull(`test`.`t1`.`a`) or (`test`.`t1`.`a` < 5))
|
||||||
|
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
||||||
|
DROP TABLE t1;
|
||||||
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
@ -890,7 +890,7 @@ Table Op Msg_type Msg_text
|
|||||||
test.t1 analyze status OK
|
test.t1 analyze status OK
|
||||||
test.t2 analyze status OK
|
test.t2 analyze status OK
|
||||||
FLUSH TABLES;
|
FLUSH TABLES;
|
||||||
SET optimizer_use_condition_selectivity=3;
|
set optimizer_use_condition_selectivity=3;
|
||||||
EXPLAIN EXTENDED
|
EXPLAIN EXTENDED
|
||||||
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
|
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
@ -903,6 +903,46 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1`
|
|||||||
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
#
|
||||||
|
# Bug mdev-4363: selectivity of the condition a IS NULL OR IS NOT NULL
|
||||||
|
# with optimizer_use_condition_selectivity=3
|
||||||
|
#
|
||||||
|
set use_stat_tables = PREFERABLY;
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1),(7),(4),(7),(NULL),(2),(NULL),(4),(NULL),(NULL),(1),(3),(8),(8);
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status OK
|
||||||
|
FLUSH TABLE t1;
|
||||||
|
set optimizer_use_condition_selectivity=3;
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 28.57 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where isnull(`test`.`t1`.`a`)
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NOT NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 71.43 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` is not null)
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL OR a IS NOT NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (isnull(`test`.`t1`.`a`) or (`test`.`t1`.`a` is not null))
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL OR a < 5;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 69.39 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (isnull(`test`.`t1`.`a`) or (`test`.`t1`.`a` < 5))
|
||||||
|
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
||||||
|
DROP TABLE t1;
|
||||||
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
|
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
|
||||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||||
|
@ -483,7 +483,7 @@ INSERT INTO t2 VALUES (4),(5),(2),(5),(1),(1),(2);
|
|||||||
ANALYZE TABLE t1, t2;
|
ANALYZE TABLE t1, t2;
|
||||||
FLUSH TABLES;
|
FLUSH TABLES;
|
||||||
|
|
||||||
SET optimizer_use_condition_selectivity=3;
|
set optimizer_use_condition_selectivity=3;
|
||||||
|
|
||||||
EXPLAIN EXTENDED
|
EXPLAIN EXTENDED
|
||||||
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
|
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
|
||||||
@ -495,4 +495,36 @@ DROP TABLE t1,t2;
|
|||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug mdev-4363: selectivity of the condition a IS NULL OR IS NOT NULL
|
||||||
|
--echo # with optimizer_use_condition_selectivity=3
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
set use_stat_tables = PREFERABLY;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1),(7),(4),(7),(NULL),(2),(NULL),(4),(NULL),(NULL),(1),(3),(8),(8);
|
||||||
|
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
FLUSH TABLE t1;
|
||||||
|
|
||||||
|
set optimizer_use_condition_selectivity=3;
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL;
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NOT NULL;
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL OR a IS NOT NULL;
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE a IS NULL OR a < 5;
|
||||||
|
|
||||||
|
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
|
||||||
|
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
@ -3303,7 +3303,8 @@ double records_in_column_ranges(PARAM *param, uint idx,
|
|||||||
key_range *min_endp, *max_endp;
|
key_range *min_endp, *max_endp;
|
||||||
min_endp= range.start_key.length? &range.start_key : NULL;
|
min_endp= range.start_key.length? &range.start_key : NULL;
|
||||||
max_endp= range.end_key.length? &range.end_key : NULL;
|
max_endp= range.end_key.length? &range.end_key : NULL;
|
||||||
rows= get_column_range_cardinality(field, min_endp, max_endp);
|
rows= get_column_range_cardinality(field, min_endp, max_endp,
|
||||||
|
range.range_flag);
|
||||||
if (HA_POS_ERROR == rows)
|
if (HA_POS_ERROR == rows)
|
||||||
{
|
{
|
||||||
total_rows= HA_POS_ERROR;
|
total_rows= HA_POS_ERROR;
|
||||||
|
@ -3339,7 +3339,8 @@ double get_column_avg_frequency(Field * field)
|
|||||||
|
|
||||||
double get_column_range_cardinality(Field *field,
|
double get_column_range_cardinality(Field *field,
|
||||||
key_range *min_endp,
|
key_range *min_endp,
|
||||||
key_range *max_endp)
|
key_range *max_endp,
|
||||||
|
uint range_flag)
|
||||||
{
|
{
|
||||||
double res;
|
double res;
|
||||||
TABLE *table= field->table;
|
TABLE *table= field->table;
|
||||||
@ -3353,12 +3354,15 @@ double get_column_range_cardinality(Field *field,
|
|||||||
|
|
||||||
double col_non_nulls= tab_records - col_nulls;
|
double col_non_nulls= tab_records - col_nulls;
|
||||||
|
|
||||||
|
bool nulls_incl= field->null_ptr && min_endp && min_endp->key[0] &&
|
||||||
|
!(range_flag & NEAR_MIN);
|
||||||
|
|
||||||
if (col_non_nulls < 1)
|
if (col_non_nulls < 1)
|
||||||
res= 0;
|
res= 0;
|
||||||
else if (min_endp && max_endp && min_endp->length == max_endp->length &&
|
else if (min_endp && max_endp && min_endp->length == max_endp->length &&
|
||||||
!memcmp(min_endp->key, max_endp->key, min_endp->length))
|
!memcmp(min_endp->key, max_endp->key, min_endp->length))
|
||||||
{
|
{
|
||||||
if (field->null_ptr && min_endp->key[0])
|
if (nulls_incl)
|
||||||
{
|
{
|
||||||
/* This is null single point range */
|
/* This is null single point range */
|
||||||
res= col_nulls;
|
res= col_nulls;
|
||||||
@ -3416,6 +3420,8 @@ double get_column_range_cardinality(Field *field,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
res= col_non_nulls;
|
res= col_non_nulls;
|
||||||
|
if (nulls_incl)
|
||||||
|
res+= col_nulls;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,8 @@ double get_column_avg_frequency(Field * field);
|
|||||||
|
|
||||||
double get_column_range_cardinality(Field *field,
|
double get_column_range_cardinality(Field *field,
|
||||||
key_range *min_endp,
|
key_range *min_endp,
|
||||||
key_range *max_endp);
|
key_range *max_endp,
|
||||||
|
uint range_flag);
|
||||||
|
|
||||||
class Histogram
|
class Histogram
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user