放弃函数,正确使用索引,我意外收获500工资

学习不是立竿见影的,而是潜移默化的。程序员的分水岭一般是在阅读源码,看书学习底层原理、底层实现机制上。我个人深有感触!

最近写了不少关于 MySQL 方面的知识,不知道大家喜欢不喜欢?如果感兴趣,我希望能找到一起学习的人!下面这本《高性能 MySQL》让我重新认识了自己的不足,我以前只是一个数据库小小白而已。

话说,最近我们有一个报表查询,随着线上数据了的大爆发,导致查询越来越越慢。Boss 说了好多次,我们技术团队都给延期了。原本以为 Boss 就忘了这件事了,谁知道今天 Boss 又在技术群里说到,说把报表这一块给我优化好,我给他加薪 500。

有谁和钱会过不去呢?我第一时间抢答,我来解决。于是我去看了相关代码,发现在统计查询的时候,Where 字段中用到了函数。SQL 简化如下所示:

select * from xttblog where month(create_time) = 5;

上面 SQL 中,create_time 是有索引的。

相信不少人看到这句 SQL,就会说:“索引上使用函数,不会走索引的”。但实际上,你用 explain 分析,却不是这样。这是因为我前面的文章写到的走索引和顺序扫描问题。

另外,在面试中,再延伸一下,为什么不会使用索引?你该怎么回答。

放弃函数,正确使用索引,我意外收获500工资
MySQL B+ tree 索引

这就要从根上来说 B+ 树的索引了。简化如上图所示,对日期字段的索引树抽象结构。现在来看,我们的索引上的日期是“2018-01-01”这样的类型,而 month(create_time) 计算出来的数值是月份,很明显和索引上的值差别很大。因此 MySQL 再执行时放弃了索引扫码,而是使用了顺序扫描。因此查询会很慢。

那么该如何优化这条 SQL 呢?很简单,上面不是按顺序扫描吗?我们让 MySQL 按索引扫描不就行了吗?所以,我们简单的改动一下 SQL,如下所示:

select * from xttblog where create_time >= '2019-05-01' AND create_time <= '2019-05-31';

你看,有时候思路也很重要。并且理解 MySQL 的底层原理也很重要。最后感谢 Boss 的助攻!

这个问题,另外还有很多种解决方法。比如,表中的数据该迁移的,可以归档到历史表中等。请不要把业务和技术选择限定的太死!

放弃函数,正确使用索引,我意外收获500工资

: » 放弃函数,正确使用索引,我意外收获500工资

原创文章,作者:bd101bd101,如若转载,请注明出处:https://blog.ytso.com/252425.html

(0)
上一篇 2022年5月4日
下一篇 2022年5月4日

相关推荐

发表回复

登录后才能评论