Loading mysql-test/r/status.result +48 −0 Original line number Diff line number Diff line Loading @@ -43,3 +43,51 @@ SHOW STATUS LIKE 'max_used_connections'; Variable_name Value Max_used_connections 4 SET GLOBAL thread_cache_size=@save_thread_cache_size; CREATE TABLE t1 ( a INT ); INSERT INTO t1 VALUES (1), (2); SELECT a FROM t1 LIMIT 1; a 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 2.402418 EXPLAIN SELECT a FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 2.402418 SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; a 1 2 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 0.000000 EXPLAIN SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 2 UNION t1 ALL NULL NULL NULL NULL 2 NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL Using filesort SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 0.000000 SELECT a IN (SELECT a FROM t1) FROM t1 LIMIT 1; a IN (SELECT a FROM t1) 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 0.000000 SELECT (SELECT a FROM t1 LIMIT 1) x FROM t1 LIMIT 1; x 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 0.000000 SELECT * FROM t1 a, t1 b LIMIT 1; a a 1 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 4.805836 DROP TABLE t1; mysql-test/t/status.test +32 −0 Original line number Diff line number Diff line Loading @@ -139,4 +139,36 @@ disconnect con3; disconnect con2; disconnect con1; # # Bug #30377: EXPLAIN loses last_query_cost when used with UNION # CREATE TABLE t1 ( a INT ); INSERT INTO t1 VALUES (1), (2); SELECT a FROM t1 LIMIT 1; SHOW SESSION STATUS LIKE 'Last_query_cost'; EXPLAIN SELECT a FROM t1; SHOW SESSION STATUS LIKE 'Last_query_cost'; SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; SHOW SESSION STATUS LIKE 'Last_query_cost'; EXPLAIN SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; SHOW SESSION STATUS LIKE 'Last_query_cost'; SELECT a IN (SELECT a FROM t1) FROM t1 LIMIT 1; SHOW SESSION STATUS LIKE 'Last_query_cost'; SELECT (SELECT a FROM t1 LIMIT 1) x FROM t1 LIMIT 1; SHOW SESSION STATUS LIKE 'Last_query_cost'; SELECT * FROM t1 a, t1 b LIMIT 1; SHOW SESSION STATUS LIKE 'Last_query_cost'; DROP TABLE t1; # End of 5.0 tests sql/sql_lex.h +22 −0 Original line number Diff line number Diff line Loading @@ -1257,6 +1257,28 @@ typedef struct st_lex : public Query_tables_list void reset_n_backup_query_tables_list(Query_tables_list *backup); void restore_backup_query_tables_list(Query_tables_list *backup); /** @brief check if the statement is a single-level join @return result of the check @retval TRUE The statement doesn't contain subqueries, unions and stored procedure calls. @retval FALSE There are subqueries, UNIONs or stored procedure calls. */ bool is_single_level_stmt() { /* This check exploits the fact that the last added to all_select_list is on its top. So select_lex (as the first added) will be at the tail of the list. */ if (&select_lex == all_selects_list && !sroutines.records) { DBUG_ASSERT(!all_selects_list->next_select_in_list()); return TRUE; } return FALSE; } } LEX; struct st_lex_local: public st_lex Loading sql/sql_select.cc +6 −2 Original line number Diff line number Diff line Loading @@ -4401,9 +4401,13 @@ choose_plan(JOIN *join, table_map join_tables) /* Store the cost of this query into a user variable Don't update last_query_cost for 'show status' command Don't update last_query_cost for 'show status' command. Don't update last_query_cost for statements that are not "flat joins" : i.e. they have subqueries, unions or call stored procedures. TODO: calculate a correct cost for a query with subqueries and UNIONs. */ if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS) if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS && join->thd->lex->is_single_level_stmt()) join->thd->status_var.last_query_cost= join->best_read; DBUG_RETURN(FALSE); } Loading Loading
mysql-test/r/status.result +48 −0 Original line number Diff line number Diff line Loading @@ -43,3 +43,51 @@ SHOW STATUS LIKE 'max_used_connections'; Variable_name Value Max_used_connections 4 SET GLOBAL thread_cache_size=@save_thread_cache_size; CREATE TABLE t1 ( a INT ); INSERT INTO t1 VALUES (1), (2); SELECT a FROM t1 LIMIT 1; a 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 2.402418 EXPLAIN SELECT a FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 2.402418 SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; a 1 2 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 0.000000 EXPLAIN SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 2 UNION t1 ALL NULL NULL NULL NULL 2 NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL Using filesort SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 0.000000 SELECT a IN (SELECT a FROM t1) FROM t1 LIMIT 1; a IN (SELECT a FROM t1) 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 0.000000 SELECT (SELECT a FROM t1 LIMIT 1) x FROM t1 LIMIT 1; x 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 0.000000 SELECT * FROM t1 a, t1 b LIMIT 1; a a 1 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value Last_query_cost 4.805836 DROP TABLE t1;
mysql-test/t/status.test +32 −0 Original line number Diff line number Diff line Loading @@ -139,4 +139,36 @@ disconnect con3; disconnect con2; disconnect con1; # # Bug #30377: EXPLAIN loses last_query_cost when used with UNION # CREATE TABLE t1 ( a INT ); INSERT INTO t1 VALUES (1), (2); SELECT a FROM t1 LIMIT 1; SHOW SESSION STATUS LIKE 'Last_query_cost'; EXPLAIN SELECT a FROM t1; SHOW SESSION STATUS LIKE 'Last_query_cost'; SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; SHOW SESSION STATUS LIKE 'Last_query_cost'; EXPLAIN SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; SHOW SESSION STATUS LIKE 'Last_query_cost'; SELECT a IN (SELECT a FROM t1) FROM t1 LIMIT 1; SHOW SESSION STATUS LIKE 'Last_query_cost'; SELECT (SELECT a FROM t1 LIMIT 1) x FROM t1 LIMIT 1; SHOW SESSION STATUS LIKE 'Last_query_cost'; SELECT * FROM t1 a, t1 b LIMIT 1; SHOW SESSION STATUS LIKE 'Last_query_cost'; DROP TABLE t1; # End of 5.0 tests
sql/sql_lex.h +22 −0 Original line number Diff line number Diff line Loading @@ -1257,6 +1257,28 @@ typedef struct st_lex : public Query_tables_list void reset_n_backup_query_tables_list(Query_tables_list *backup); void restore_backup_query_tables_list(Query_tables_list *backup); /** @brief check if the statement is a single-level join @return result of the check @retval TRUE The statement doesn't contain subqueries, unions and stored procedure calls. @retval FALSE There are subqueries, UNIONs or stored procedure calls. */ bool is_single_level_stmt() { /* This check exploits the fact that the last added to all_select_list is on its top. So select_lex (as the first added) will be at the tail of the list. */ if (&select_lex == all_selects_list && !sroutines.records) { DBUG_ASSERT(!all_selects_list->next_select_in_list()); return TRUE; } return FALSE; } } LEX; struct st_lex_local: public st_lex Loading
sql/sql_select.cc +6 −2 Original line number Diff line number Diff line Loading @@ -4401,9 +4401,13 @@ choose_plan(JOIN *join, table_map join_tables) /* Store the cost of this query into a user variable Don't update last_query_cost for 'show status' command Don't update last_query_cost for 'show status' command. Don't update last_query_cost for statements that are not "flat joins" : i.e. they have subqueries, unions or call stored procedures. TODO: calculate a correct cost for a query with subqueries and UNIONs. */ if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS) if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS && join->thd->lex->is_single_level_stmt()) join->thd->status_var.last_query_cost= join->best_read; DBUG_RETURN(FALSE); } Loading