2016-07-28 27 views
1

Wie questions hier in einigen other etabliert „Unterabfrage“ in MySQL löschen Ursachen es langsamer zu sein, während gleich „die Option“ Abfrage führt schnell mit:Warum kann MySQL DELETE keine Indizes für Unterabfragen verwenden?

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) 

Zu wissen, die Indizes verwenden JOIN kann, würde ich gerne Experten fragen:

Was verhindert, dass MySQL/MariaDB Indizes in DELETE mit SUBQUERY verwendet? Ist das ein Implementierungsproblem oder gibt es ein konzeptionelles Problem? Gibt es Pläne, das zu lösen? Betrifft das gleiche Problem andere SQL-Anbieter?

Antwort

2

Unterabfragen sind abgeleitete Tabellen und werden nicht materialisiert. Sie manifestieren sich in temporären Tabellen.

Wie ich schrieb in this answer:

Das Dokument Derived Tables in MySQL 5.7 es für gut Versionen 5.6 und 5.7 beschrieben, wobei letztere aufgrund die Änderung materialisiert abgeleitet Tabellenausgabe eingebaut wird keine Strafe bieten wird in die äußere Abfrage. In früheren Versionen wurde ein erheblicher Overhead mit temporären Tabellen mit dem abgeleiteten Programm ertragen.

1

Verwenden Sie nicht IN (SELECT ...). Verwenden Sie stattdessen eine Multitabelle DELETE wie hier beschrieben: http://dev.mysql.com/doc/refman/5.5/en/delete.html

Dabei werden gegebenenfalls Indizes verwendet.

+0

Haben Sie die Frage gelesen? – romaninsh

+0

Ich denke, Rick konzentrierte sich auf einen anderen Aspekt, als würde er es anders machen, als das Verhalten der Unteranfrage zu erklären. Das heißt, weit gefehlt ist es von mir bis zu diesem [Docs Multi-Table Delete] (http://stackoverflow.com/documentation/mysql/1487/delete/8768/multi-table-deletes#t=201607292124449831703). – Drew