新手问题 mysql 为什么不走索引?

spfzzz · 2018年11月16日 · 最后由 IDbbnn345 回复于 2018年11月18日 · 3470 次阅读

在家闲来无聊, 发现下面的 SQL 不走索引,哪位大神帮忙解释一下....

Create Table: CREATE TABLE `catalogs` (
  ....
  `catalog_type` varchar(255) NOT NULL DEFAULT '' COMMENT 'type of catalog',
  `parent_id` int(11) NOT NULL DEFAULT '0' COMMENT 'the parent''s id',
  `status` int(11) NOT NULL DEFAULT '0' COMMENT 'status of catalog',
  .....
  KEY `index_catalogs_on_catalog_type_and_status_and_parent_id` (`catalog_type`,`status`,`parent_id`)
) ENGINE=InnoDB AUTO_INCREMENT=108 DEFAULT CHARSET=utf8

正如上面执行的结构,Mysql 的 InnerDB 不是最左匹配原则吗?为什么 SQL 查询时 catalog_type 的为 user-menu 时,不走索引而是全表扫描?而为 user_menu 时走索引了?

索引失效理论上和字段值没什么关系吧

建议贴一下表结构

或者数据太少了? 全表扫描更快? 不知道这个是不是偶然现象 你多查几次 还是这个结果吗

来个 code 模板吧。。。

建议用 https://www.db-fiddle.com 把信息帖全

mysterytree 回复

应该是数据太少了,增加了数据后,在执行都走索引了

mysterytree 回复

但好像也不是数据量的问题,把数据再清除后,再执行还是走索引😐

mysterytree 回复

在添加数据前,执行了三次都是不走索引的

我是这样理解的 @spfzzz MySQL 在查询的时候 查询优化器会通过统计信息(从 innnodb 获取,例如索引,页等信息)估算查询成本(单位是读取一个 4k 数据页的成本), 来评估查询方案, 然后将最优方案发送给存储引擎执行。 因为查询成本受到不同因素影响,在数据比较少的时候,可能就会计算出来不走索引比走索引更优,出现全表扫描的情况,这也就是为啥你执行的时候结果随机的原因。如果数据特别多, 走索引肯定比全表扫描快,那应该是稳稳的走索引。

话说贴代码别贴图片, @hooopo 炮哥建议的好

KEY index_catalogs_on_catalog_type_and_status_and_parent_id (catalog_type,status,parent_id) 看上去应该是三个条件都要有才会用到索引?不太了解 MySQL,PG 是这样的。

nouse 回复

MySQL 联合索引会走的

朋飞在家研究的很彻底啊😎 原来还有这种操作

AB联合索引
where A = ? AND B = ? //命中索引
where A = ? //命中索引
where B = ? //不命中索引
kevinyu 回复

这不是找不到工作嘛,闲的蛋疼就看看咯;而且身体也不舒服,在家休息的呗

spfzzz 回复

搞搞 GO 或者 java 吧 好找一点 ruby 我最近看了 机会很少了,而且现在不是招聘季了

kevinyu 回复

Go 已经看了一点儿了,在大学的时候就学的 java,那个时候还是 jdk6.0,现在都 9 了吧,已经赶不上了

kevinyu 回复

不管学什么语言,数据库的东西都需要掌握

mysterytree 回复

明白了。就是说 InnoDB 的索引虽然采用的 B+tree 结构,大原则上也遵循最左匹配;但是真正执行查询的时候,会根据实际情况,不一定会走索引。有一问题咨询一下,如果 SQL 已经被缓存了(Mysql 开启了查询缓存),是不是也不走索引了,而是拿到缓存的数据直接返回应用层。

懒得追寻原因就 force index 一下……

luikore 回复

是可以这样做;但还是想知道走索引和不走索引到底是根据什么判断的

《数据库索引设计和优化》这本书不知道有没有介绍走索引的依据。先看看吧

spfzzz 回复

缓存命中应该是不走索引直接 return 但是加了 explain 参数后 应该会穿透缓存去执行
飞哥是要在家修炼一段时间杀回北京啊

mysterytree 回复

谢谢胡的解答。北京要饭的成本太高,不被饿死就不错了。

mysterytree 回复

家里还有两亩地呢

#10 解释的很清楚了 你可以用 mysql 的 optimizer trace 这个功能看一下优化器到底考虑了什么

liprais 回复

多谢大神指点

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册