Mysql
UPDATE 不使用 INDEX,但 SELECT 使用
我實際上正在努力理解這裡的問題。我到處讀到說 UPDATE 受益於 WHERE 子句上的索引。
但是,這個查詢,
UPDATE `documents` SET `read`="1" WHERE `docid` IN (<subquery>)
似乎沒有使用索引。該表
documents
有一個索引 ondocid
和 onread
。當我執行 時
EXPLAIN
,我看到possible_keys = NULL
和rows = 8011008
(全表)。子查詢確實使用鍵並讀取正確的行(2 行)。另一方面,這個查詢:
SELECT * FROM `documents` WHERE `docid` IN (<subquery>)
確實使用索引
docid
並且執行速度非常快。它讀取的行數比需要的多(根據EXPLAIN
),但完全可以接受。對此有什麼解釋嗎?
我使用 MariaDB 10。
作為一個有趣的註釋(關於
SELECT
),如果在<subquery>
我使用 aUNION
時,子查詢似乎獲得了正確的行數,但似乎主查詢不使用索引並進行全表掃描。如果在
UPDATE
I 中使用JOIN
而不是IN
,則正確使用索引。我通過使用解決了我的問題JOIN
。
為了解決“UPDATE 不使用 INDEX,但 SELECT 使用”的問題…
直到最近,許多
UPDATEs
都是由不同的程式碼處理的SELECTs
。最近,Oracle 分支進行了統一。我認為它還沒有進入 MariaDB。此外,在
IN ( SELECT ... )
5.6 之前,該結構的優化非常差。同樣,MariaDB 可能包含也可能尚未包含該領域的一些 5.6/5.7 改進。
... IN ( SELECT ... )
變成幾乎總是更好JOIN ... ON ...
。這在UPDATE
; 請參閱“多表更新”。有關您的具體案例的更多討論,請提供
SHOW CREATE TABLE
和EXPLAIN SELECT ...
。我並不是說 Oracle 分支一定會做得更好。而是可能存在差異。