Hi, Alexander! On May 04, Alexander Barkov wrote:
@@ -2513,7 +2530,14 @@ void Item_func_nullif::update_used_tables() } else { - Item_func::update_used_tables(); + /* + No needs to iterate through args[2] when it's just a copy of args[0]. + See MDEV-9712 Performance degradation of nested NULLIF + */ + DBUG_ASSERT(arg_count == 3); + used_tables_and_const_cache_init(); + used_tables_and_const_cache_update_and_join(args[0] == args[2] ? 2 : 3, + args);
here, you can unconditionally run
used_tables_and_const_cache_update_and_join(2, args);
because even if args[2] differs from args[0], it cannot use more tables, so for the purpose of this method, it's redundant.
I'm not sure.
After equal const propagation, update_used_tables() is called again 2 times in this script:
DROP TABLE IF EXISTS t1; CREATE TABLE t1 (a BINARY(1)); INSERT INTO t1 VALUES ('a'),('b'); SELECT * FROM t1 WHERE NULLIF(a,'a') IS NULL AND a='a';
<offtopic> Btw, update_used_tables() is called: - 3 times before propagate_equal_fields() - 2 times after propagate_equal_fields() Perhaps we should generally try to reduce the amount of update_used_tables(). </offtopic>
Perhaps. We're in general walking the tree too much, I think.
When update_used_tables() is called after propagate_equal_fields(), args[0] can already be a constant, while args[2] can still point to the original expression involving tables.
So args[2] can have more tables, it seems.
Can you clarify please?
Then I was wrong :) I thought it'll be just a cast or charset convertion on top of args[0] (or the other way around), and forgot about constant substitution. Regards, Sergei Chief Architect MariaDB and security@mariadb.org