Nun*_*uno 3 mysql innodb mariadb index mariadb-10.1
我实际上很难理解这里的问题。我到处都看到说 UPDATE 受益于 WHERE 子句上的索引。
然而,这个查询,
UPDATE `documents` SET `read`="1" WHERE `docid` IN (<subquery>)
Run Code Online (Sandbox Code Playgroud)
似乎没有使用索引。该表documents有一个索引 ondocid和 on read。
当我执行 时EXPLAIN,我看到possible_keys = NULL和rows = 8011008(全表)。子查询确实使用键并读取正确的行(2 行)。
另一方面,这个查询:
SELECT * FROM `documents` WHERE `docid` IN (<subquery>)
Run Code Online (Sandbox Code Playgroud)
确实使用索引docid并且运行速度非常快。它读取的行数比需要的多(根据EXPLAIN),但完全可以接受。
对此有什么解释吗?
我使用 MariaDB 10。
作为一个有趣的注释(关于SELECT),如果在<subquery>我使用 aUNION时,虽然子查询似乎获得了正确的行数,但主查询似乎不使用索引并进行全表扫描。
如果在UPDATEI useJOIN而不是 中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 分支一定会做得更好;而是说 Oracle 分支一定会做得更好。相反,可能存在差异。