From 973fb9962c2caef8b021f32cfc3bbd686adb1c46 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 9 Oct 2008 12:50:29 +0500 Subject: [PATCH] Bug#38918 selecting from information_schema.columns is disproportionately slow The problem: table_open_method is not calculated properly if '*' is used in 'select' The fix: added table_open_method calculation for such case --- mysql-test/r/information_schema.result | 9 +++++++++ mysql-test/t/information_schema.test | 8 ++++++++ sql/sql_show.cc | 12 +++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index c5c79b15ca6..c198e097b96 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1646,4 +1646,13 @@ drop table t1; drop function f1; select * from information_schema.tables where 1=sleep(100000); select * from information_schema.columns where 1=sleep(100000); +explain select count(*) from information_schema.tables; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE tables ALL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases +explain select count(*) from information_schema.columns; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE columns ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases +explain select count(*) from information_schema.views; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE views ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases End of 5.1 tests. diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index bb9cb127d07..4027293da66 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1338,4 +1338,12 @@ where state='User sleep' and info='select * from information_schema.columns where 1=sleep(100000)'; --source include/wait_condition.inc + +# +# Bug#38918 selecting from information_schema.columns is disproportionately slow +# +explain select count(*) from information_schema.tables; +explain select count(*) from information_schema.columns; +explain select count(*) from information_schema.views; + --echo End of 5.1 tests. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f715da843c2..f2b02d0107f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2962,7 +2962,7 @@ static int fill_schema_table_names(THD *thd, TABLE *table, @retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE */ -static uint get_table_open_method(TABLE_LIST *tables, +uint get_table_open_method(TABLE_LIST *tables, ST_SCHEMA_TABLE *schema_table, enum enum_schema_tables schema_table_idx) { @@ -2973,12 +2973,22 @@ static uint get_table_open_method(TABLE_LIST *tables, { Field **ptr, *field; int table_open_method= 0, field_indx= 0; + uint star_table_open_method= OPEN_FULL_TABLE; + bool used_star= true; // true if '*' is used in select for (ptr=tables->table->field; (field= *ptr) ; ptr++) { + star_table_open_method= + min(star_table_open_method, + schema_table->fields_info[field_indx].open_method); if (bitmap_is_set(tables->table->read_set, field->field_index)) + { + used_star= false; table_open_method|= schema_table->fields_info[field_indx].open_method; + } field_indx++; } + if (used_star) + return star_table_open_method; return table_open_method; } /* I_S tables which use get_all_tables but can not be optimized */