首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL覆盖指数与类算子

问MySQL覆盖指数与类算子
EN

Stack Overflow用户
提问于 2015-09-23 10:10:47
回答 2查看 651关注 0票数 3

我正在读“高性能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子句的子查询中找到匹配的行时。

我不明白为什么,类似的声明还在.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-12 05:07:15

我假设这张桌子是InnoDB。

代码语言:javascript
复制
SELECT prod_id
     FROM products
     WHERE actor='SEAN CARREY' AND title LIKE '%APOLLO%'

在INDEX(actor, title, prod_id)中处理,因为它是“覆盖”。

代码语言:javascript
复制
SELECT * FROM ...

因为(我猜想) *中还有很多其他字段,所以没有“覆盖”。

他们展示的“诀窍”是:

  1. 根据比表小得多的假设,做索引中的所有搜索。注意:索引是一个BTree;表是一个不同的BTree。
  2. 获取步骤1中的PRIMARY KEY值,即获取prod_id的列表。
  3. 通过在表*中使用PRIMARY KEY有效地查找其余的数据( products )。

假设有40行actor='SEAN CARREY',其中只有3行有title LIKE '%APOLLO%'。让我们比较两种方法:

代码语言:javascript
复制
SELECT * FROM products
    WHERE actor='SEAN CARREY' AND title LIKE '%APOLLO%'
  1. 查看INDEX(actor, ...),找到40 prod_id。
  2. 深入数据40次。
  3. 过滤掉那些没有所需的title。
  4. 送3排。

在I/O绑定(阅读:巨表)中,这将是I/O计数:

  1. 1块可能包含所有40个索引项;它们将在一起,因为索引的第一部分是相同的。
  2. 需要在桌子上看近40个街区。

总计:约41个工作单位。

现在查看带有子查询的查询。

  1. 只扫描索引。再过一个街区。
  2. 将手伸进主表4次。

共计:4个工作单位。

4 << 41,因此更复杂的查询实际上运行得更快。(你不太可能看到整个10倍的进步-因为我遗漏了很多细节。)

票数 2
EN

Stack Overflow用户

发布于 2015-09-23 10:16:48

由于索引是从左到右的工作,所以如果要使用索引,则左侧不应该是可变的-

如果您的标题字段是索引的,那么检查如下所示-

代码语言:javascript
复制
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将只使用此索引。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32736736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档