mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-7487 Semi-join optimization for single-table update/delete statements
This patch allows to use semi-join optimization at the top level of single-table update and delete statements. The problem of supporting such optimization became easy to resolve after processing a single-table update/delete statement started using JOIN structure. This allowed to use JOIN::prepare() not only for multi-table updates/deletes but for single-table ones as well. This was done in the patch for mdev-28883: Re-design the upper level of handling UPDATE and DELETE statements. Note that JOIN::prepare() detects all subqueries that can be considered as candidates for semi-join optimization. The code added by this patch looks for such candidates at the top level and if such candidates are found in the processed single-table update/delete the statement is handled in the same way as a multi-table update/delete. Approved by Oleksandr Byelkin <sanja@mariadb.com>
This commit is contained in:
@ -218,14 +218,16 @@ INSERT INTO t2 VALUES (1), (2), (3);
|
||||
#
|
||||
EXPLAIN UPDATE t1 SET a = 10 WHERE 1 IN (SELECT 1 FROM t2 WHERE t2.b < 3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
|
||||
FLUSH STATUS;
|
||||
FLUSH TABLES;
|
||||
EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE 1 IN (SELECT 1 FROM t2 WHERE t2.b < 3);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
# Status of EXPLAIN EXTENDED query
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
@ -246,8 +248,9 @@ Handler_read_key 4
|
||||
Handler_read_rnd_next 5
|
||||
# Status of testing query execution:
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
Handler_read_rnd_next 5
|
||||
Handler_read_key 5
|
||||
Handler_read_rnd 3
|
||||
Handler_read_rnd_next 12
|
||||
Handler_update 3
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
@ -263,13 +266,13 @@ INSERT INTO t2 VALUES (1), (2), (3);
|
||||
EXPLAIN UPDATE t1 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t1.a < 3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1)
|
||||
FLUSH STATUS;
|
||||
FLUSH TABLES;
|
||||
EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t1.a < 3);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; FirstMatch(t1)
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
||||
# Status of EXPLAIN EXTENDED query
|
||||
@ -900,14 +903,16 @@ INSERT INTO t2 VALUES (1), (2), (3), (1000);
|
||||
#
|
||||
EXPLAIN UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
|
||||
FLUSH STATUS;
|
||||
FLUSH TABLES;
|
||||
EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
|
||||
# Status of EXPLAIN EXTENDED query
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
@ -928,8 +933,8 @@ Handler_read_key 4
|
||||
Handler_read_rnd_next 9
|
||||
# Status of testing query execution:
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
Handler_read_rnd_next 10
|
||||
Handler_read_key 7
|
||||
Handler_read_rnd_next 8
|
||||
Handler_update 3
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
@ -986,14 +991,14 @@ INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
|
||||
#
|
||||
EXPLAIN DELETE FROM t1 WHERE a1 IN (SELECT a2 FROM t2 WHERE a2 > 2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t1)
|
||||
FLUSH STATUS;
|
||||
FLUSH TABLES;
|
||||
EXPLAIN EXTENDED DELETE FROM t1 WHERE a1 IN (SELECT a2 FROM t2 WHERE a2 > 2);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; FirstMatch(t1)
|
||||
# Status of EXPLAIN EXTENDED query
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
@ -2823,14 +2828,14 @@ INSERT INTO t2 VALUES (1), (2), (3);
|
||||
EXPLAIN UPDATE t1 SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||
2 DEPENDENT SUBQUERY <derived3> unique_subquery distinct_key distinct_key 5 func 1
|
||||
1 PRIMARY <derived3> ref key0 key0 5 test.t1.a 2 FirstMatch(t1)
|
||||
3 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort
|
||||
FLUSH STATUS;
|
||||
FLUSH TABLES;
|
||||
EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY <derived3> unique_subquery distinct_key distinct_key 5 func 1 100.00
|
||||
1 PRIMARY <derived3> ref key0 key0 5 test.t1.a 2 100.00 FirstMatch(t1)
|
||||
3 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using filesort
|
||||
# Status of EXPLAIN EXTENDED query
|
||||
Variable_name Value
|
||||
|
Reference in New Issue
Block a user