Commit 480957e7 authored by sergefp@mysql.com's avatar sergefp@mysql.com

Fix for BUG#9622: Make index statistics collection in MyISAM behave the same

way in ALTER TABLE ... ENABLE KEYS, ANALYZE TABLE and after bulk insert:
now statistics collection always assumes NULLs are inequal. 
parent b580a12d
...@@ -3243,6 +3243,9 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a) ...@@ -3243,6 +3243,9 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey, cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE, (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
&diff_pos); &diff_pos);
ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
&diff_pos);
sort_param->unique[diff_pos-1]++; sort_param->unique[diff_pos-1]++;
} }
else else
...@@ -3955,7 +3958,38 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, ...@@ -3955,7 +3958,38 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
return; return;
} }
/* calculate unique keys for each part key */
/*
Update statistics for each part of an index
SYNOPSIS
update_key_parts()
keyinfo Index information (only key->keysegs used)
rec_per_key_part OUT Store statistics here
unique IN Array of #distinct values collected over index
run.
records Number of records in the table
NOTES
Unique is an array:
unique[0]= (#different values of {keypart1}) - 1
unique[1]= (#different values of {keypart2,keypart1} tuple) - unique[0] - 1
...
Here we assume that NULL != NULL (see SEARCH_NULL_ARE_NOT_EQUAL). The
'unique' array is collected in one sequential scan through the entire
index. This is done in two places: in chk_index() and in sort_key_write().
Output is an array:
rec_per_key_part[k] =
= E(#records in the table such that keypart_1=c_1 AND ... AND
keypart_k=c_k for arbitrary constants c_1 ... c_k)
= {assuming that values have uniform distribution and index contains all
tuples from the domain (or that {c_1, ..., c_k} tuple is choosen from
index tuples}
= #tuples-in-the-index / #distinct-tuples-in-the-index.
*/
void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part, void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
ulonglong *unique, ulonglong records) ulonglong *unique, ulonglong records)
......
...@@ -581,3 +581,17 @@ check table t1; ...@@ -581,3 +581,17 @@ check table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
drop table t1; drop table t1;
create table t1 (a int, key(a));
insert into t1 values (1),(2),(3),(4),(NULL),(NULL),(NULL),(NULL);
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A 8 NULL NULL YES BTREE
alter table t1 disable keys;
alter table t1 enable keys;
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A 8 NULL NULL YES BTREE
drop table t1;
...@@ -560,3 +560,18 @@ update t1 set c2='A B' where c1=2; ...@@ -560,3 +560,18 @@ update t1 set c2='A B' where c1=2;
check table t1; check table t1;
drop table t1; drop table t1;
# BUG#9622 - ANALYZE TABLE and ALTER TABLE .. ENABLE INDEX produce
# different statistics on the same table with NULL values.
create table t1 (a int, key(a));
insert into t1 values (1),(2),(3),(4),(NULL),(NULL),(NULL),(NULL);
analyze table t1;
show keys from t1;
alter table t1 disable keys;
alter table t1 enable keys;
show keys from t1;
drop table t1;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment