Commit dd119466 authored by Igor Babaev's avatar Igor Babaev

Addressed the following issues from the review of the patch:

1. The PERSISTENT FOR clause of the ANALYZE command overrides
the setting of the system variable use_stat_tables: 
with this clause ANALYZE unconditionally collects persistent
statistics.
2. ANALYZE collects persistent statistics only for tables of
the USER category. So it never collects persistent statistics
for system tables.  
parent 81563081
...@@ -1016,11 +1016,73 @@ test t1 idx1 2 NULL ...@@ -1016,11 +1016,73 @@ test t1 idx1 2 NULL
test t1 idx4 1 6.2000 test t1 idx4 1 6.2000
test t1 idx4 2 NULL test t1 idx4 2 NULL
test t1 idx4 3 NULL test t1 idx4 3 NULL
DROP TABLE t1,t2;
DELETE FROM mysql.table_stats; DELETE FROM mysql.table_stats;
DELETE FROM mysql.column_stats; DELETE FROM mysql.column_stats;
DELETE FROM mysql.index_stats; DELETE FROM mysql.index_stats;
ANALYZE TABLE mysql.column_stats PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
mysql.column_stats analyze error Invalid argument
ANALYZE TABLE mysql.column_stats;
Table Op Msg_type Msg_text
mysql.column_stats analyze status OK
SELECT * FROM mysql.table_stats;
db_name table_name cardinality
SELECT * FROM mysql.column_stats;
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency
SELECT * FROM mysql.index_stats;
db_name table_name index_name prefix_arity avg_frequency
set use_stat_tables='never'; set use_stat_tables='never';
ANALYZE TABLE t1 PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date
SELECT * FROM mysql.table_stats;
db_name table_name cardinality
test t1 40
SELECT * FROM mysql.column_stats;
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency
test t1 a 0 49 0.0000 4.0000 1.0000
test t1 c aaaa dddddddd 0.1250 6.6571 7.0000
test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000
test t1 e 0.01 0.112 0.2250 8.0000 6.2000
test t1 f 1 5 0.2000 1.0000 6.4000
test t1 b NULL NULL 0.2000 17.1250 NULL
SELECT * FROM mysql.index_stats;
db_name table_name index_name prefix_arity avg_frequency
test t1 PRIMARY 1 1.0000
test t1 idx3 1 8.5000
test t1 idx2 1 7.0000
test t1 idx2 2 2.3846
test t1 idx1 1 NULL
test t1 idx1 2 NULL
test t1 idx4 1 6.2000
test t1 idx4 2 NULL
test t1 idx4 3 NULL
SELECT * FROM mysql.table_stats;
db_name table_name cardinality
test t1 40
SELECT * FROM mysql.column_stats;
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency
test t1 a 0 49 0.0000 4.0000 1.0000
test t1 c aaaa dddddddd 0.1250 6.6571 7.0000
test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000
test t1 e 0.01 0.112 0.2250 8.0000 6.2000
test t1 f 1 5 0.2000 1.0000 6.4000
test t1 b NULL NULL 0.2000 17.1250 NULL
SELECT * FROM mysql.index_stats;
db_name table_name index_name prefix_arity avg_frequency
test t1 PRIMARY 1 1.0000
test t1 idx3 1 8.5000
test t1 idx2 1 7.0000
test t1 idx2 2 2.3846
test t1 idx1 1 NULL
test t1 idx1 2 NULL
test t1 idx4 1 6.2000
test t1 idx4 2 NULL
test t1 idx4 3 NULL
DELETE FROM mysql.table_stats;
DELETE FROM mysql.column_stats;
DELETE FROM mysql.index_stats;
DROP TABLE t1,t2;
set names utf8; set names utf8;
CREATE DATABASE world; CREATE DATABASE world;
use world; use world;
......
...@@ -397,14 +397,39 @@ ANALYZE TABLE t1; ...@@ -397,14 +397,39 @@ ANALYZE TABLE t1;
SELECT * FROM mysql.column_stats; SELECT * FROM mysql.column_stats;
SELECT * FROM mysql.index_stats; SELECT * FROM mysql.index_stats;
DROP TABLE t1,t2;
DELETE FROM mysql.table_stats; DELETE FROM mysql.table_stats;
DELETE FROM mysql.column_stats; DELETE FROM mysql.column_stats;
DELETE FROM mysql.index_stats; DELETE FROM mysql.index_stats;
ANALYZE TABLE mysql.column_stats PERSISTENT FOR ALL;
ANALYZE TABLE mysql.column_stats;
SELECT * FROM mysql.table_stats;
SELECT * FROM mysql.column_stats;
SELECT * FROM mysql.index_stats;
set use_stat_tables='never'; set use_stat_tables='never';
ANALYZE TABLE t1 PERSISTENT FOR ALL;
SELECT * FROM mysql.table_stats;
SELECT * FROM mysql.column_stats;
SELECT * FROM mysql.index_stats;
SELECT * FROM mysql.table_stats;
SELECT * FROM mysql.column_stats;
SELECT * FROM mysql.index_stats;
DELETE FROM mysql.table_stats;
DELETE FROM mysql.column_stats;
DELETE FROM mysql.index_stats;
DROP TABLE t1,t2;
set names utf8; set names utf8;
CREATE DATABASE world; CREATE DATABASE world;
......
...@@ -650,6 +650,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -650,6 +650,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
TABLE *tab= table->table; TABLE *tab= table->table;
Field **field_ptr= tab->field; Field **field_ptr= tab->field;
if (lex->with_persistent_for_clause &&
tab->s->table_category != TABLE_CATEGORY_USER)
{
compl_result_code= result_code= HA_ADMIN_INVALID;
}
if (!lex->column_list) if (!lex->column_list)
{ {
uint fields= 0; uint fields= 0;
...@@ -711,7 +717,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -711,7 +717,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (compl_result_code == HA_ADMIN_OK && if (compl_result_code == HA_ADMIN_OK &&
operator_func == &handler::ha_analyze && operator_func == &handler::ha_analyze &&
thd->variables.use_stat_tables > 0) table->table->s->table_category == TABLE_CATEGORY_USER &&
(thd->variables.use_stat_tables > 0 ||
lex->with_persistent_for_clause))
{ {
if (!(compl_result_code= if (!(compl_result_code=
alloc_statistics_for_table(thd, table->table)) && alloc_statistics_for_table(thd, table->table)) &&
......
...@@ -458,6 +458,7 @@ void lex_start(THD *thd) ...@@ -458,6 +458,7 @@ void lex_start(THD *thd)
lex->set_var_list.empty(); lex->set_var_list.empty();
lex->param_list.empty(); lex->param_list.empty();
lex->view_list.empty(); lex->view_list.empty();
lex->with_persistent_for_clause= FALSE;
lex->column_list= NULL; lex->column_list= NULL;
lex->index_list= NULL; lex->index_list= NULL;
lex->prepared_stmt_params.empty(); lex->prepared_stmt_params.empty();
......
...@@ -2452,6 +2452,7 @@ struct LEX: public Query_tables_list ...@@ -2452,6 +2452,7 @@ struct LEX: public Query_tables_list
this command. this command.
*/ */
bool parse_vcol_expr; bool parse_vcol_expr;
bool with_persistent_for_clause; // uses PERSISTENT FOR clause (in ANALYZE)
enum SSL_type ssl_type; /* defined in violite.h */ enum SSL_type ssl_type; /* defined in violite.h */
enum enum_duplicates duplicates; enum enum_duplicates duplicates;
......
...@@ -7258,7 +7258,10 @@ opt_persistent_stat_clause: ...@@ -7258,7 +7258,10 @@ opt_persistent_stat_clause:
/* empty */ /* empty */
{} {}
| PERSISTENT_SYM FOR_SYM persistent_stat_spec | PERSISTENT_SYM FOR_SYM persistent_stat_spec
{} {
THD *thd= YYTHD;
thd->lex->with_persistent_for_clause= TRUE;
}
; ;
persistent_stat_spec: persistent_stat_spec:
......
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