我正在读“高性能MySQL",O‘’Reilly,第二版。第122页:
MySQL不能在索引中执行类似的操作。等
在同一页中,后面的示例是(对参与者、标题、prod_id有一个索引):
EXPLAIN SELECT * FROM products JOIN ( SELECT prod_id FROM products WHERE actor='SEAN CARREY' AND title LIKE '%APOLLO%' ) AS t1 ON (t1.prod_id=products.prod_id)\G
然后,它指出:
现在,MySQL在查询的第一阶段使用覆盖索引,当它在FROM子句的子查询中找到匹配的行时。
我不明白为什么,类似的声明还在.
发布于 2015-10-12 05:07:15
我假设这张桌子是InnoDB。
SELECT prod_id
FROM products
WHERE actor='SEAN CARREY' AND title LIKE '%APOLLO%'在INDEX(actor, title, prod_id)中处理,因为它是“覆盖”。
SELECT * FROM ...因为(我猜想) *中还有很多其他字段,所以没有“覆盖”。
他们展示的“诀窍”是:
PRIMARY KEY值,即获取prod_id的列表。*中使用PRIMARY KEY有效地查找其余的数据( products )。假设有40行actor='SEAN CARREY',其中只有3行有title LIKE '%APOLLO%'。让我们比较两种方法:
SELECT * FROM products
WHERE actor='SEAN CARREY' AND title LIKE '%APOLLO%'INDEX(actor, ...),找到40 prod_id。title。在I/O绑定(阅读:巨表)中,这将是I/O计数:
总计:约41个工作单位。
现在查看带有子查询的查询。
共计:4个工作单位。
4 << 41,因此更复杂的查询实际上运行得更快。(你不太可能看到整个10倍的进步-因为我遗漏了很多细节。)
发布于 2015-09-23 10:16:48
由于索引是从左到右的工作,所以如果要使用索引,则左侧不应该是可变的-
如果您的标题字段是索引的,那么检查如下所示-
title like '%APOLLO%' : Will not use index
title like '%APOLLO' : Will not use index
title like 'APOLLO%' : Will use index
title like 'APOLLO' : Will use index在您的情况下,子查询是不需要的,因为您可以通过简单查询获得相同的结果,如果对参与者字段进行了索引,那么query将只使用此索引。
https://stackoverflow.com/questions/32736736
复制相似问题