Reputation: 10664
As established in some other questions here, using "subquery" in MySQL delete causes it to be slower, while identical "select" query performs fast:
MariaDB [as_01_import]> explain select * from invoice_payment where invoice_id in (select id from dochead where system_id = 5786);
+------+-------------+-----------------+------+---------------------------------------+----------------------------+---------+-------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------------+------+---------------------------------------+----------------------------+---------+-------------------------+------+-------------+
| 1 | PRIMARY | dochead | ref | PRIMARY,dochead_system_id | dochead_system_id | 4 | const | 891 | Using index |
| 1 | PRIMARY | invoice_payment | ref | invoice_payment_invoice_fk,invoice_id | invoice_payment_invoice_fk | 4 | as_01_import.dochead.id | 1 | |
+------+-------------+-----------------+------+---------------------------------------+----------------------------+---------+-------------------------+------+-------------+
MariaDB [as_01_import]> explain delete from invoice_payment where invoice_id in (select id from dochead where system_id = 5786);
+------+--------------------+-----------------+-----------------+---------------------------+---------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------------+-----------------+-----------------+---------------------------+---------+---------+------+---------+-------------+
| 1 | PRIMARY | invoice_payment | ALL | NULL | NULL | NULL | NULL | 1235451 | Using where |
| 2 | DEPENDENT SUBQUERY | dochead | unique_subquery | PRIMARY,dochead_system_id | PRIMARY | 4 | func | 1 | Using where |
+------+--------------------+-----------------+-----------------+---------------------------+---------+---------+------+---------+-------------+
2 rows in set (0.44 sec)
Knowing that JOIN can use indexes, I would like to ask experts:
What prevents MySQL / MariaDB from using indexes in DELETE with SUBQUERY? Is that an implementation problem or is there a conceptual problem? Are there any plans to solve this? Is the same problem affecting other SQL vendors?
Upvotes: 1
Views: 1691
Reputation: 142298
Do not use IN ( SELECT ... )
. Instead, use a multi-table DELETE
as described here: http://dev.mysql.com/doc/refman/5.5/en/delete.html
Doing so will make use of indexes where applicable.
Upvotes: 2
Reputation: 24959
Subqueries are derived tables and are not materialized. They are manifested in temporary tables.
As I wrote in this answer:
The document Derived Tables in MySQL 5.7 describes it well for versions 5.6 and 5.7, where the latter will provide no penalty due to the change in materialized derived table output being incorporated into the outer query. In prior versions, substantial overhead was endured with temporary tables with the derived.
Upvotes: 2