1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

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.
This commit is contained in:
Evgeny Potemkin
2009-12-02 00:25:51 +03:00
parent 9e5d1bb664
commit 987e146604
11 changed files with 352 additions and 5 deletions

View File

@@ -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=
@@ -17141,6 +17145,41 @@ bool JOIN::change_result(select_result *res)
DBUG_RETURN(FALSE);
}
/**
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)
*/