私は実際にここで問題を理解するのに苦労しています。私は、UPDATEがWHERE句のインデックスから利益を得ると言ってどこでも読みました。
ただし、このクエリは、
UPDATE `documents` SET `read`="1" WHERE `docid` IN (<subquery>)
しないインデックスを使用しているようです。テーブルdocuments
には、docid
とread
のインデックスがあります。
EXPLAIN
を実行すると、possible_keys = NULL
およびrows = 8011008
(テーブル全体)が表示されます。サブクエリはキーを使用し、適切な行(2行)を読み取ります。
一方、このクエリは:
SELECT * FROM `documents` WHERE `docid` IN (<subquery>)
使用しますdocid
のインデックスで、非常に高速に実行されます。 (EXPLAIN
のように)必要以上の行を読み取りますが、完全に許容されます。
これについて何か説明はありますか?
私はMariaDB 10を使用しています。
おもしろいメモとして(SELECT
に関して)、<subquery>
でUNION
を使用している場合、サブクエリは適切な数の行を取得しているように見えますが、プライマリクエリはインデックスを使用せず、テーブル全体をスキャンします。
UPDATE
でJOIN
の代わりにIN
を使用すると、インデックスが適切に使用されます。 JOIN
を使用して問題を解決しました。
「UPDATEはINDEXを使用しませんが、SELECTは使用します」という質問に対処するには...
ごく最近まで、UPDATEs
の多くはSELECTs
とは異なるコードで処理されていました。最近、Oracleブランチに統合がありました。 MariaDBにはまだ導入されていないと思います。
また、構造体IN ( SELECT ... )
は、5.6まで最適化されていません。この場合も、MariaDBには、この領域の5.6/5.7の改善の一部がまだ含まれている場合と含まれていない場合があります。
ほとんどの場合、... IN ( SELECT ... )
をJOIN ... ON ...
に変換することをお勧めします。これはUPDATE
で可能です。 「マルチテーブルUPDATE」を参照してください。
特定のケースの詳細については、SHOW CREATE TABLE
およびEXPLAIN SELECT ...
を提供してください。
Oracleブランチが必然的に物事をより良いものにするということではありません。むしろ違いがあるかもしれないということです。