Mysql

UPDATE 不使用 INDEX,但 SELECT 使用

  • October 25, 2016

我實際上正在努力理解這裡的問題。我到處讀到說 UPDATE 受益於 WHERE 子句上的索引。

但是,這個查詢,

UPDATE `documents` SET `read`="1" WHERE `docid` IN (<subquery>)

似乎沒有使用索引。該表documents有一個索引 ondocid和 on read

當我執行 時EXPLAIN,我看到possible_keys = NULLrows = 8011008(全表)。子查詢確實使用鍵並讀取正確的行(2 行)。

另一方面,這個查詢:

SELECT * FROM `documents` WHERE `docid` IN (<subquery>)

確實使用索引docid並且執行速度非常快。它讀取的行數比需要的多(根據EXPLAIN),但完全可以接受。

對此有什麼解釋嗎?

我使用 MariaDB 10。

作為一個有趣的註釋(關於SELECT),如果在<subquery>我使用 aUNION時,子查詢似乎獲得了正確的行數,但似乎主查詢不使用索引並進行全表掃描。

如果在UPDATEI 中使用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 TABLEEXPLAIN SELECT ...

我並不是說 Oracle 分支一定會做得更好。而是可能存在差異。

引用自:https://dba.stackexchange.com/questions/153293