MySQL覆盖索引和类运算符
我正在阅读高性能MySQL,O'Reilly,第二版。 第122页: MySQL无法在索引中执行类似的操作。等 在同一页中,后面的示例是关于actor、title、prod_id的索引: 解释选择* 来自产品 参加 选择产品标识 来自产品 演员class='SEAN CARREY'和标题像''%APOLLO%' 与t1.prod\u id=products.prod\u id\G上的t1相同 然后声明: 现在,MySQL在查询的第一阶段使用覆盖索引,当它在FROM子句的子查询中找到匹配的行时MySQL覆盖索引和类运算符,mysql,query-optimization,query-performance,Mysql,Query Optimization,Query Performance,我正在阅读高性能MySQL,O'Reilly,第二版。 第122页: MySQL无法在索引中执行类似的操作。等 在同一页中,后面的示例是关于actor、title、prod_id的索引: 解释选择* 来自产品 参加 选择产品标识 来自产品 演员class='SEAN CARREY'和标题像''%APOLLO%' 与t1.prod\u id=products.prod\u id\G上的t1相同 然后声明: 现在,MySQL在查询的第一阶段使用覆盖索引,当它在FROM子句的子查询中找到匹配的行时 我
我不明白为什么,LIKE语句仍然存在…因为索引是从左到右工作的,所以如果要使用索引,左侧不应该是可变的- 如果您的标题字段已编入索引,请按照以下步骤进行检查-
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
在您的情况下,不需要子查询,因为您可以通过简单查询获得相同的结果,并且如果对actor字段进行了索引,那么查询将仅使用此索引。我假设该表是InnoDB
在索引器、标题、产品id中处理,因为它是覆盖的
SELECT * FROM ...
未涵盖,因为我假设*中有许多其他字段
他们展示的技巧是:
在索引中执行所有搜索,前提是索引比表小得多。注:该索引为B树;这张桌子是另一棵树。
从步骤1中获取主键值。也就是说,获取产品id的列表。
通过在表产品中使用主键,高效地查找其余数据*。
假设演员“肖恩·凯利”共有40行,其中只有3行的标题类似于“阿波罗%”。让我们比较两种方法:
SELECT * FROM products
WHERE actor='SEAN CARREY' AND title LIKE '%APOLLO%'
查看索引器。。。查找40个产品id。
将数据覆盖40次。
过滤掉那些没有合适标题的。
送3行。
在I/O绑定的read:MARGE表中,这将是I/O计数:
1块可能包含所有40个索引项;他们会在一起,因为索引的第一部分是相同的。
需要在表格中查看近40个街区。
总计:约41个工作单元
现在查看带有子查询的查询
只扫描索引。再过一个街区。
将手伸进主桌4次。
总计:4个工作单元
4…查询的第一阶段。。。actor=SEAN CARREY标准包含在索引中。@raina77谢谢,让我理解。。。所以它使用索引,但是对于actor='SEAN CARREY'的记录,它会执行一个普通的表访问来执行类似的操作?谢谢。我仍然不明白的是,为什么指数会覆盖。LIKE语句不是带前缀的形式,本书声明在这种情况下不能使用索引。。。所以你的1。只扫描索引应该是无效的…覆盖-将索引器、标题、prod_id视为一个包含这3列的表,该索引是它的主键。然后问我能不能选择。。。从那张桌子上得到我想要的东西?答案是肯定的。然而,它不会是非常理想的,因为领先的%。
SELECT * FROM products
WHERE actor='SEAN CARREY' AND title LIKE '%APOLLO%'