Mysql 'where 索引列=xx and 非索引列=yy' 有时候不走索引?

发布于 2022-09-11 16:03:02 字数 1145 浏览 69 评论 0

如题, 我一直以为 select * from 表 where 索引列=xx and 非索引列=yy 一定会走索引列的索引.
但是今天发现, 并不是这样.
经测试(MySQL 5.6.16):

  1. 当联合条件能够匹配到记录时, 索引.
  2. 当联合条件不能匹配到记录时, 不走索引.

按照我的预期, mysql优化器用索引列扫描, 没有找到, 直接返回不就得了, 不用再管后面的非索引列了.
但是, 按照上面的测试来看, 很有可能是, 先走索引列, 发现没有对应的记录, 然后全表扫描了下.

另外, 即使使用了force index (索引列的索引)依旧是上面的情形.

示例:

id是索引列, content_type是非索引列.

联合条件匹配无记录时

clipboard.png

联合条件无匹配记录时

clipboard.png

测试表的结构

clipboard.png

开启prifiling后

执行SQL:
select sql_no_cache * from 表 force index(primary) where id=5 and content_type='电话'; (联合条件匹配不到记录的场景)

查看profile信息:
clipboard.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鸵鸟症 2022-09-18 16:03:02

你这个例子怎么看出没用索引呢?你的id和content_type列都属于主键索引的索引内容,也就是说,你的查询是在一个const table里面进行,所以查不到数据会显示Impossible WHERE noticed after reading const tables。其他情况一般是显示using where的。
这里的Impossible WHERE是告诉你,在主键索引里,没找到你想要的行,主键也是索引呢,别歧视他,老铁。
另外,你要做实验,应该用非主键索引来弄。

清风不识月 2022-09-18 16:03:02

开启 profiling 后再执行看看, explain 和真实执行的可能不一样, 从截图上看 id 是主键并且是等值查询,会走索引才对, 把表结构拿出来看看

profiling开启方法

# 开启
set profiling = 1

# 执行语句
...

# 查看所有语句
show profiles

# 查看语句具体的执行情况
show frofile for query query_number

====== 回复分割线 =======

上面说错一个地方,profiling 能看到执行使用资源,不能看到是否用索引

我在 5.7 版本(刚好测试环境有)下执行这个查询语句:

Extra 显示的是 no matching row in const table

然后去官网看了一下 explain 的输出解析

意思就是在唯一索引里面找不到相应的数据, 文档里面有说用到索引去查询,至于怎么证明,还没想到

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文