diff options
author | Igor Babaev <igor@askmonty.org> | 2012-12-05 22:51:11 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2012-12-05 22:51:11 -0800 |
commit | dd119466c35d621d191d4d4ddcb578cb02420bdc (patch) | |
tree | 518ab13e2d7a160c82745c348f27c4b1253f8ee7 | |
parent | 81563081e5fb6f016d5be845af55234869a5fb61 (diff) | |
download | mariadb-git-dd119466c35d621d191d4d4ddcb578cb02420bdc.tar.gz |
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.
-rw-r--r-- | mysql-test/r/statistics.result | 64 | ||||
-rw-r--r-- | mysql-test/t/statistics.test | 29 | ||||
-rw-r--r-- | sql/sql_admin.cc | 10 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 5 |
6 files changed, 105 insertions, 5 deletions
diff --git a/mysql-test/r/statistics.result b/mysql-test/r/statistics.result index ecb252d4c01..e3f4d6bf564 100644 --- a/mysql-test/r/statistics.result +++ b/mysql-test/r/statistics.result @@ -1016,11 +1016,73 @@ test t1 idx1 2 NULL test t1 idx4 1 6.2000 test t1 idx4 2 NULL test t1 idx4 3 NULL -DROP TABLE t1,t2; DELETE FROM mysql.table_stats; DELETE FROM mysql.column_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'; +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; CREATE DATABASE world; use world; diff --git a/mysql-test/t/statistics.test b/mysql-test/t/statistics.test index cfe66879c27..4537c4ed3f3 100644 --- a/mysql-test/t/statistics.test +++ b/mysql-test/t/statistics.test @@ -397,14 +397,39 @@ ANALYZE TABLE t1; SELECT * FROM mysql.column_stats; SELECT * FROM mysql.index_stats; -DROP TABLE t1,t2; - DELETE FROM mysql.table_stats; DELETE FROM mysql.column_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'; + +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; CREATE DATABASE world; diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 6044207eeaa..f2124dd3bb8 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -650,6 +650,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, TABLE *tab= table->table; 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) { uint fields= 0; @@ -711,7 +717,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (compl_result_code == HA_ADMIN_OK && 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= alloc_statistics_for_table(thd, table->table)) && diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f6e2ca09ec9..23eaf3b7258 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -458,6 +458,7 @@ void lex_start(THD *thd) lex->set_var_list.empty(); lex->param_list.empty(); lex->view_list.empty(); + lex->with_persistent_for_clause= FALSE; lex->column_list= NULL; lex->index_list= NULL; lex->prepared_stmt_params.empty(); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index fd7d22c26be..e034e06bfef 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2452,6 +2452,7 @@ struct LEX: public Query_tables_list this command. */ 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 enum_duplicates duplicates; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a71e30bc548..3de03297163 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7258,7 +7258,10 @@ opt_persistent_stat_clause: /* empty */ {} | PERSISTENT_SYM FOR_SYM persistent_stat_spec - {} + { + THD *thd= YYTHD; + thd->lex->with_persistent_for_clause= TRUE; + } ; persistent_stat_spec: |