abc 联合索引查 bc 走不走索引

2020-03-24 08:31:52 +08:00
 gssong

abc 联合索引查 bc 走不走索引 我觉得按照最左前缀匹配不走,可是面试官说走,说看看 MySQL 内部优化啥的,有没有大佬解答一下

9559 次点击
所在节点    MySQL
56 条回复
gssong
2020-03-24 09:59:01 +08:00
@fancy111
可是 Using where: 仅仅表示 MySQL 服务器在收到存储引擎返回的记录后进行“后过滤”( Post-filter )。 不管 SQL 语句的执行计划是全表扫描( type=ALL)或非唯一性索引扫描( type=ref)
raysonlu
2020-03-24 10:00:06 +08:00
项目实践中发现,你的搜索条件只有 ABC 的时候,你怎么写顺序都没问题,没有什么最左原则匹配,但如果出现了一个条件 D 后,就不一定了,有时候 BCD 走索引,有时候不走,其实这些都是 MYSQL 解析语句的时候有个步骤是优化语句,看你有无开这个,尽管开了也看它是否人工智能(zhang)帮你优化到尽量用索引,这视乎你的语句复杂度和建立的索引种类,2200 年了,MYSQL 简单的优化还是有的。
ahsjs
2020-03-24 10:03:01 +08:00
@raysonlu 说的是没有 A 的时候,讨论的应该不是优化这个
gssong
2020-03-24 10:06:31 +08:00
@xiaxiaocao 我觉得可能是理解错面试官意思了,他可能问的索引包括这个联合索引之外的索引
gssong
2020-03-24 10:11:12 +08:00
@ahsjs 和楼下的结果 type 是 index
xsm1890
2020-03-24 10:14:31 +08:00
最左前缀原则
fancy111
2020-03-24 10:14:32 +08:00
@gssong 是的,所以这只是文字游戏,实际上没有用到我们说的索引,只是有可能优化得好查询的时候不是全表,而是之前留下的缓存表。
littlewing
2020-03-24 10:18:01 +08:00
走索引,但是不走索引
littlewing
2020-03-24 10:18:40 +08:00
@littlewing 顺序扫描索引,你可以说是走了,也可以说是没走。这样玩文字游戏的面试官直接扇他巴掌
opengps
2020-03-24 10:20:19 +08:00
回归下索引本身,想想大字典,因为找了 a 才能找到 b,然后才能找到 c,所以不从头开始的索引都没法使用
pangsq
2020-03-24 10:23:32 +08:00
explain 一把试试。
1. 用的 mysql 5.6.40 ,innodb
2. create table abcd (a varchar(255), b varchar(255), c varchar(255), d varcahr(255));
3. alter table abcd add index abc(a,b,c);
4. explain select a,b from abcd; # using index
5. explain select b,c from abcd; # using index
6. explain select c,d from abcd; # null
EmdeBoas
2020-03-24 10:24:34 +08:00
@dovme 走了,因为二级索引里面已经包含了所有要的字段数据,所以去扫二级索引的树,不用回表;你改一下表结构,新增一些字段结果就不同了,不会命中索引
baozijun
2020-03-24 10:28:55 +08:00
我错了...看了下文档,发现只用 bc 的话还是会遍历索引 叶子节点进行查找,找到了 b 节点会顺着往下找到 c,所以还是走了索引. @dovme 我感觉 联合索引不用加上主键,因为默认生成的主键(聚簇)索引已经覆盖了.
ahsjs
2020-03-24 10:30:09 +08:00
@pangsq 大佬 d varchar 都打错了,确定试了?
gssong
2020-03-24 10:31:37 +08:00
表中有 abc 三个字段,都是 int 类型,执行出来 type=index extra 为 Using where; Using index
表中有 abcd 四个字段,都是 int 类型,执行出来 type = all extra 为 Using where
aliipay
2020-03-24 10:39:30 +08:00
@gssong 是 index 还是 all 和 select 内容有关的
xman99
2020-03-24 10:40:37 +08:00
包含 a 的话走, 如果是 innodb 引擎,b 存在普通二级索引, 也可以使用到索引的。abc 联合索引,需要包含 a 字段才会生效的
dovme
2020-03-24 10:43:51 +08:00
@EmdeBoas #32 你是对的,我新增一个字段 d,然后还是执行刚才的 sql,没有走索引.
pangsq
2020-03-24 10:46:41 +08:00
@ahsjs == 见谅,先在 mysql 里跑的后敲在这的,没复制
awanganddong
2020-03-24 11:05:56 +08:00
联合索引,给我感觉就是多字段联合排序,先按 A 排,再按 B 排。但是实际上,这个问题比较复杂,必须由示例而定,毕竟查询优化器会选择,如果工作上遇到还是 explain 一波。

有些跑题了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/655560

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX