summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorEvgeny Potemkin <epotemkin@mysql.com>2009-12-02 00:25:51 +0300
committerEvgeny Potemkin <epotemkin@mysql.com>2009-12-02 00:25:51 +0300
commit987e146604d741f13fa03b7cb5e4af1cf3e30324 (patch)
treef6897e6f5c940d328bb17f29511b4e7dc729185b /sql/sql_select.cc
parent9e5d1bb6647c88e5a60c2a3e7eadc76fd1089135 (diff)
downloadmariadb-git-987e146604d741f13fa03b7cb5e4af1cf3e30324.tar.gz
Bug#33546: Slowdown on re-evaluation of constant expressions.
Constant expressions in WHERE/HAVING/ON clauses aren't cached and evaluated for each row. This causes slowdown of query execution especially if constant UDF/SP function are used. Now WHERE/HAVING/ON expressions are analyzed in the top-bottom direction with help of the compile function. When analyzer meets a constant item it sets a flag for the tree transformer to cache the item and doesn't allow tree walker to go deeper. Thus, the topmost item of a constant expression if cached. This is done after all other optimizations were applied to WHERE/HAVING/ON expressions A helper function called cache_const_exprs is added to the JOIN class. It calls compile method with caching analyzer and transformer on WHERE, HAVING, ON expressions if they're present. The cache_const_expr_analyzer and cache_const_expr_transformer functions are added to the Item class. The first one check if the item can be cached and the second caches it if so. A new Item_cache_datetime class is derived from the Item_cache class. It caches both int and string values of the underlying item independently to avoid DATETIME aware int-to-string conversion. Thus it completely relies on the ability of the underlying item to correctly convert DATETIME value from int to string and vice versa. mysql-test/r/func_like.result: A test case result is corrected after fixing bug#33546. mysql-test/r/func_time.result: A test case result is corrected after fixing bug#33546. mysql-test/r/select.result: Added a test case for the bug#33546. mysql-test/r/subselect.result: A test case result is corrected after fixing bug#33546. mysql-test/r/udf.result: Added a test case for the bug#33546. mysql-test/t/select.test: Added a test case for the bug#33546. mysql-test/t/udf.test: Added a test case for the bug#33546. sql/item.cc: Bug#33546: Slowdown on re-evaluation of constant expressions. The cache_const_expr_analyzer and cache_const_expr_transformer functions are added to the Item class. The first one check if the item can be cached and the second caches it if so. Item_cache_datetime class implementation is added. sql/item.h: Bug#33546: Slowdown on re-evaluation of constant expressions. Item_ref and Item_cache classes now returns basic_const_item from underlying item. The cache_const_expr_analyzer and cache_const_expr_transformer functions are added to the Item class. sql/sql_select.cc: Bug#33546: Slowdown on re-evaluation of constant expressions. A helper function called cache_const_exprs is added to the JOIN class. It calls compile method with caching analyzer and transformer on WHERE, HAVING, ON expressions if they're present. sql/sql_select.h: Bug#33546: Slowdown on re-evaluation of constant expressions. A helper function called cache_const_exprs is added to the JOIN class.
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc39
1 files changed, 39 insertions, 0 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f035e28da5c..65ff44622a8 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1076,6 +1076,10 @@ JOIN::optimize()
{
conds=new Item_int((longlong) 0,1); // Always false
}
+
+ /* Cache constant expressions in WHERE, HAVING, ON clauses. */
+ cache_const_exprs();
+
if (make_join_select(this, select, conds))
{
zero_result_cause=
@@ -17142,5 +17146,40 @@ bool JOIN::change_result(select_result *res)
}
/**
+ Cache constant expressions in WHERE, HAVING, ON conditions.
+*/
+
+void JOIN::cache_const_exprs()
+{
+ bool cache_flag= FALSE;
+ bool *analyzer_arg= &cache_flag;
+
+ /* No need in cache if all tables are constant. */
+ if (const_tables == tables)
+ return;
+
+ if (conds)
+ conds->compile(&Item::cache_const_expr_analyzer, (uchar **)&analyzer_arg,
+ &Item::cache_const_expr_transformer, (uchar *)&cache_flag);
+ cache_flag= FALSE;
+ if (having)
+ having->compile(&Item::cache_const_expr_analyzer, (uchar **)&analyzer_arg,
+ &Item::cache_const_expr_transformer, (uchar *)&cache_flag);
+
+ for (JOIN_TAB *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
+ {
+ if (*tab->on_expr_ref)
+ {
+ cache_flag= FALSE;
+ (*tab->on_expr_ref)->compile(&Item::cache_const_expr_analyzer,
+ (uchar **)&analyzer_arg,
+ &Item::cache_const_expr_transformer,
+ (uchar *)&cache_flag);
+ }
+ }
+}
+
+
+/**
@} (end of group Query_Optimizer)
*/