1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-9712 Performance degradation of nested NULLIF

10.1 introduced a problem:
Execution time for various recursive stages
(walk, update_used_table, and propagate_equal_fields)
in NULLIF is O(recursion_level^2), because complexity is
doubled on every recursion level when we copy args[0] to args[2].

This change fixes to avoid unnecessary recursion in:
- Item_func_nullif::walk
- Item_func_nullif::update_used_tables
- Item_func_nullif::propagate_equal_fields
when possible.
This commit is contained in:
Alexander Barkov
2016-05-05 15:39:04 +04:00
parent 19c4d22a1e
commit a87507eec3
2 changed files with 37 additions and 4 deletions

View File

@@ -1026,6 +1026,7 @@ public:
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
void fix_length_and_dec();
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
uint decimal_precision() const { return args[2]->decimal_precision(); }
const char *func_name() const { return "nullif"; }
void print(String *str, enum_query_type query_type);
@@ -1037,13 +1038,21 @@ public:
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
Context cmpctx(ANY_SUBST, cmp.compare_type(), cmp.compare_collation());
const Item *old0= args[0];
args[0]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
cond, &args[0]);
args[1]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
cond, &args[1]);
args[2]->propagate_equal_fields_and_change_item_tree(thd,
Context_identity(),
cond, &args[2]);
/*
MDEV-9712 Performance degradation of nested NULLIF
ANY_SUBST is more relaxed than IDENTITY_SUBST.
If ANY_SUBST did not change args[0],
then we can skip propagation for args[2].
*/
if (old0 != args[0])
args[2]->propagate_equal_fields_and_change_item_tree(thd,
Context_identity(),
cond, &args[2]);
return this;
}
};