小白白跑去鹅厂面试,面试官提出了一个很实际的问题: mysql增加索引,那些情况会失效呢?谈一下实际工作中遇到的情况。我们的小白白又抛出了白氏秘籍:用不用索引,找DBA小姐姐!啊?这是你面试哈,还是DBA小姐姐面试呀。(更多信息,请关注微信公众号: 白白家族)


一 概述

日常处理mysql问题中,往往通过增加索引来提高查询速度,但在有些情况下,执行过程中并没有按照我们的预期结果执行,也就是说,即使字段加了索引,但现实也没有使用到,到底是什么地方出了差错,以下我们将一探究竟。


二 实验表结构声明:

我们将对以下表结构进行实际案例分析

CREATETABLE `student` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `age` int(11) DEFAULT 0,  `name` varchar(16) DEFAULT "",  key idx_age (`age`),  key idx_name (`name`),  PRIMARY KEY (`id`)) ENGINE=InnoDB;

三 Mysql不走索引归类以及详细解析

根据实验表做具体case分析,归纳为以下几点:

1. 查询条件在索引列上使用函数操作,或者运算的情况

例如以下case是不走索引的:

explain select * from student where abs(age) =18;explain select * from student where age + 1=18;

2. 查询条件字符串和数字之间的隐式转换

例如:name与age分别做字符串/数字(88)的隐式转换;

以下case走索引情况:

explain select * from student where name =’88’; explain select * from student where age='88'; explain select * from student where age =88;

以下case不走索引情况:

explain select * from student where name=88;

3. 特殊修饰符 %%, Or 将不走索引

explain select * from student where name like'%name%' ;explain select * from student where name ='name' or age = 18;

4. 索引优化器选择最优的索引

这一点最重要,索引到底用不用,不是列加了索引就一定会用,而是根据索引优化器来决定。

索引优化器的存在,就是找到一个索引扫描行数最少的方案去执行语句。那么扫描行数怎么来判断的?是逐行统计数据表的数据吗?其实并不是,而是根据统计信息来估算的值。这个统计信息就是我们常说的索引的“区分度”。

显然,一个索引上不同的值越多,这个索引的区分度就越好。我们把一个索引上不同的值的个数,称之为“索引基数”。也就是说,基数越大,索引的区分度就越好,执行查询的行数就越少。如何查看索引基数呢?使用 show index from 表名,cardinality字段显示的就是索引的基数。

扩展:MySQL 是怎样得到索引基数的呢?不感兴趣的小伙伴可以飘过啦。

索引基数 = 采样统计*页数。采样统计就是避免把整张表取出来一行行统计做精准计算,以免消耗系统性能。在采样统计时,InnoDB默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。统计信息不是固定不变的,他会随着数据表的变化而变化。当变更的数据行数超过 1/M 的时候,会自动触发重新做一次索引统计。

索引优化器实例一:

经常听人说,执行<>语句时,不走索引,今天我们将看一看实际执行情况,还是那句话,到底走不走,我们说了不算,还是索引优化器说了算:

看截图 ,就会发现 <> 其实是走了索引。

为什么会出现这样的情景呢?因为 student表中10W多条数据的值全都是'name',索引基数太小,所以在执行<>'1name'查询时,实际上要查询条数为10多W条,如果走了name字段索引,其实和全表查询没什么区别,况且,执行name字段索引,最终还是要转换为主键索引(二级索引查询都会转换为主键查询),所以索引优化器的优化结果是不走name索引。然而在执行<>'name'查询时,优化器优化结果是走name索引,因为,<>'name'的查询行数很小,大部分条数name字段的值都是'name'。

索引优化器实例二:

同理,前缀like匹配是走索引,但是,以下却展示了不一样的结果:

为什么会这样呢?请小伙伴们参考实例一仔细思考一下。

如何指定优化器执行固定的索引:

索引优化器的存在,我们就没办法指定强制走我们指定的索引?

答案就是通过 force index强制来实现,执行语句和分析结果如下图所示


四 总结以及实际应用

实际应用中,应该牢记上述索引优化的原则,比如在实际工作中,由于索引优化器选错索引,导致数据查询缓慢,阻塞线上业务,而当时的解决办法,就是上述文章的分析过程,以及采用force 强制索引才解决的,前车之鉴,希望广大读者避免踩坑。

更多信息请关注 微信公众号 :  白白家族
 或扫描白白家族公众号二维码:

加了索引,mysql查询就一定会用吗?相关推荐

  1. 表字段加了索引但是查询依然很慢

    之前遇到一个问题(因为最近又遇到了,所以记录下来),表字段加了索引但是查询依然很慢,大概的情况如下 问题描述: 有个表T_ORDER(匿名),字段若干,其中有个TX_TIME交易时间,MERCHANT ...

  2. mysql or走索引吗_加了索引,mysql查询就一定会用吗?

    小白白跑去鹅厂面试,面试官提出了一个很实际的问题: mysql增加索引,那些情况会失效呢?谈一下实际工作中遇到的情况.我们的小白白又抛出了白氏秘籍:用不用索引,找DBA小姐姐!啊?这是你面试哈,还是D ...

  3. 面试官:为啥加了索引查询会变快?

    面试官:你在工作中有遇到SQL查询比较慢的情况吗? 果子:有的.随着业务的发展,表中的数据量会越来越大,查询就会越来越慢 面试官:那你是如何优化查询慢的问题? 果子:在需要查询的列上加索引 面试官:那 ...

  4. mysql 查询正在执行的事务以及锁 常用的sql语句

    执行update语句报错 [Err] 1205 - Lock wait timeout exceeded; try restarting transaction 查询 正在执行的事务: ​​​​​​​ ...

  5. mysql加索引后查询时间变长了(终于有头绪了)

    在使用ip查询的地址(地址和ip对应的信息存在mysql中,使用的是myisam)的过程中遇到一个这样的问题: 给表中的一些字段加索引后查询时间变长了,cpu飙升了 该表的结构如下 这是什么原因呢难道 ...

  6. mysql千万级数据索引查询_mysql千万级数据量根据索引优化查询速度

    (一)索引的作用 索引通俗来讲就相当于书的目录,当我们根据条件查询的时候,没有索引,便需要全表扫描,数据量少还可以,一旦数据量超过百万甚至千万,一条查询sql执行往往需要几十秒甚至更多,5秒以上就已经 ...

  7. mysql 查询相同字段值的个数_好文 | MySQL 索引B+树原理,以及建索引的几大原则...

    MySQL事实上使用不同的存储引擎也是有很大区别的,下面猿友们可以了解一下. 一.存储引擎的比较 注:上面提到的B树索引并没有指出是B-Tree和B+Tree索引,但是B-树和B+树的定义是有区别的. ...

  8. mysql 前索引_MySQL查询性能优化前,必须先掌握MySQL索引理论

    数据库索引在平时的工作是必备的,怎么建好索引,怎么使用索引,可以提高数据的查询效率.而且在面试过程,数据库的索引也是必问的知识点,比如: 索引底层结构选型,那为什么选择B+树? 不同存储引擎的索引的体 ...

  9. MySQL锁机制,行锁jingran加在索引上

    锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制,应该都不陌生.?但在这之前我们先来看看并发控制,理清MVCC多版本并发控制和锁的关系,这也是之前我很迷惑的一个点 并发控制技术 在数据库中, ...

最新文章

  1. VSCODE安装必要的插件实现浏览器中打开,以及显示网址
  2. Entity Framework中的Migration问题
  3. GPT-3:人工智能的新突破
  4. 网站长尾词布置需要注意什么事项?
  5. windows7 docker mysql_DOCKER windows 7 详细安装教程
  6. 二十一世纪Windows简史
  7. python闭包函数的必要条件_Python 函数 functions、闭包 closure
  8. ML_Review_PCA(Ch4)
  9. 用三年时间培养 1W 名高素质技术人才,这是一个什么样的计划?
  10. idea svn 的使用----转载,挺好的
  11. 艾伟也谈项目管理,我的项目管理观点
  12. cru使用教程_显示器刷新率超频教程
  13. HUPlayer 使用向导和常见问题
  14. Java NIO?看这一篇就够了!
  15. 设置页眉为计算机网络,如何设置页眉从指定页开始
  16. js-for循环-9*9乘法表小练习
  17. Three.js 粒子系统动画与发光材质——利用HTML5画布绘制
  18. C语言递归函数实现十位数转换进制并打印出来(超详细)
  19. linux 怎么改系统字体,linux系统终端修改字体的方法
  20. Python面试之沪江网“数据爬虫算法实习”

热门文章

  1. 网络攻防技术——域名信息
  2. 数据库substr……in……
  3. stamps中gacos去除大气噪声
  4. 怎么让背景铺满整个页面_css新手教程之背景图充满整个屏幕
  5. c++---constructor(ctor,构造函数)
  6. php 修改图片dpi,PHP修改PNG图片DPI
  7. 光子晶体matlab,Matlab光子晶体程序讨论
  8. mysql周报内容范文_Mysql报表查询实例(日报|周报|月报|时间差自动计算)
  9. C++11特性(详细版)
  10. Python学习培训方法