2016-07-28 98 views
1

確立在某些otherquestions這裏,在MySQL中使用「子查詢」刪除的原因是要慢一些,而相同的「選擇」查詢執行速度快:爲什麼MySQL DELETE無法在子查詢上使用索引?

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) 

知道JOIN可以使用索引,我想請問專家:

是什麼阻止MySQL/MariaDB在使用SUBQUERY的DELETE中使用索引?這是一個執行問題還是存在概念問題?有沒有計劃解決這個問題?影響其他SQL供應商的是同樣的問題嗎?

回答

2

子查詢是派生表,並未實現。它們表現在臨時表格中。

正如我在this answer寫道:

文檔Derived Tables in MySQL 5.7描述它很好5.6 版本和5.7,其中後者將提供無罰由於 在物化派生表輸出的變化被結合 成外部查詢。在以前的版本中,大量的開銷是 與派生的臨時表忍受。

1

請勿使用IN (SELECT ...)。相反,使用如下所述的多表DELETEhttp://dev.mysql.com/doc/refman/5.5/en/delete.html

這樣做會在適用的情況下使用索引。

+0

你讀過這個問題了嗎? – romaninsh

+0

我認爲Rick專注於它的一些其他方面,就像做不同的事情,而不是解釋子查詢行爲。也就是說,從我這裏不是[文檔多表刪除](http://stackoverflow.com/documentation/mysql/1487/delete/8768/multi-table-deletes#t=201607292124449831703)。 – Drew