MySql中当in或or参数过多时导致索引失效
今天的文章很短只讲一件事情,但发现很多同学还不知道,以至于引发一些数据库使用层面的慢查询、访问超时问题。
mysql有个阈值,决定了阈值之下使用索引查询,而超过阈值则退化,优化器选择索引下潜,进而引起iops过高或者慢查询问题,导致超时。
大家一定要记着:MySQL优化器决定使用某个索引执行查询的仅仅是因为:使用该索引时的成本足够低。也就是说即使我们有下边的语句:
SELECT * FROM t WHERE key1 IN ('b', 'c');
MySQL优化器需要去分析一下如果使用二级索引idx_key1执行查询的话,键值在['b', 'b']和['c', 'c']这两个范围区间的记录共有多少条,然后通过一定方式计算出成本,与全表扫描的成本相对比,选取成本更低的那种方式执行查询。
MySQL优化器针对IN子句对应的范围区间的多少而指定了不同的策略:
如果IN子句对应的范围区间比较少,那么将率先去访问一下存储引擎,看一下每个范围区间中的记录有多少条(如果范围区间的记录比较少,那么统计结果就是精确的,反之会采用一定的手段计算一个模糊的值,当然算法也比较麻烦),这种在查询真正执行前优化器就率先访问索引来计算需要扫描的索引记录数量的方式称之为index dive。
如果IN子句对应的范围区间比较多,这样就不能采用index dive的方式去真正的访问二级索引idx_key1(因为那将耗费大量的时间),而是需要采用之前在背地里产生的一些统计数据去估算匹配的二级索引记录有多少条(很显然根据统计数据去估算记录条数比index dive的方式精确性差了很多)。
那什么时候采用index dive的统计方式,什么时候采用index statistic的统计方式呢?
这就取决于我们要说的系统变量eq_range_index_dive_limit的值了。
这个值在5.6版本默认是10,5.7版本默认是200,如下图:
ep_range_index_dive_limit参数提供一个阈值,优化器在预估扫描行数时,会根据这个参数,来进行预估策略。通常优化器有两种预估策略:索引统计和索引下潜。
1、当低于eq_range_index_dive_limit参数阀值时,
采用index dive方式预估影响行数,该方式优点是相对准确,
但不适合对大量值进行快速预估。
2、当大于或等于eq_range_index_dive_limit参数阀值时,
采用index statistics方式预估影响行数,
该方式优点是计算预估值的方式简单,可以快速获得预估数据,
但相对偏差较大。
在eq_range_index_dive_limit设置过小且索引分布极不均匀的情况下,MySQL可能会由于成本计算误差太大,导致选择错误的执行计划这一灾难性后果!
简单理解:
参数超过阈值,会导致索引退化,索引失效。
此规则适用于in、or:
col_name IN(val1, …, valN)
col_name = val1 OR … OR col_name = valN
怎么解决呢?
简单来说,就是我们需要控制in、or语句中的参数个数,阈值是200,但是我们代码更倾向于控制在50内,也就是说我们需要有机制识别与控制(cr方式、组件拦截方式、编码规范等)避免类似的风险被触发,而不是完全无视,极致一些,只要是in场景,就需要加limit限制。
希望对你有用。
MySql中当in或or参数过多时导致索引失效相关推荐
- bcp 不能调用where 子句_技术分享 || Mysql中IS NULL、IS NOT NULL不能走索引?
mysql中IS NULL.IS NOT NULL不能走索引? 不知道是啥原因也不知道啥时候, 江湖上流传着这么一个说法 mysql查询条件包含IS NULL.IS NOT NULL.!=.like ...
- mysql中对一个表的id建立了唯一索引,那么查询的select count(*) ,select count(1) ,select count(id),select count(列名)
1.mysql中对一个表的id建立了唯一索引,那么查询的select count(*) ,select count(1) ,select count(id),select count(列名) 的查询结 ...
- mysql left join 索引失效_MySQL索引列上做操作导致索引失效案例分析
索引列上做操作导致索引失效 通常我们认为只要建立索引就可以万事大吉,以为只要建立就一定会使用到,可其实在索引列上的计算.函数.类型转换都可能导致索引失效,所以我们不仅要会创建索引,更重要的是如何正确的 ...
- MySQL 字符集不一致导致索引失效的一个真实案例
文章目录 问题描述 问题分析 总结 大家好,我是只谈技术不剪发的 Tony 老师.今天给大家分析一个由于 MySQL 字符集不一致导致索引失效的案例. 问题描述 有个朋友给我发来一个问题,说是他们的系 ...
- mysql float 1,MySql中float类型含义及参数详解
float表示浮点数,通俗点来说的话,我们可以简单理解为小数 参数有两个: M表示精度,表示浮点数的位数 D表示标度,表示小数位数 M位数不包括小数点位数 举例:float(6,2) 则最大范围表示: ...
- mysql join 组合索引,图文详解MySQL中两表关联的连接表如何创建索引
本文介绍了MySQL中两表关联的连接表是如何创建索引的相关内容,分享出来供大家参考学习,下面来看看详细的介绍: 问题介绍 创建数据库的索引,可以选择单列索引,也可以选择创建组合索引. 遇到如下这种情况 ...
- mysql使索引失效语句_会导致索引失效语句
1.使用like关键字模糊查询时,% 放在前面索引不起作用,只有"%"不在第一个位置,索引才会生效(like '%文'–索引不起作用) 2.使用联合索引时,只有查询条件中使用了这些 ...
- 关于mysql使用!=或者<>会导致索引失效问题的验证
目录 写在前面 5.0版本,!=.<>都会造成索引失效 因为8.0的我这边有乱码,所以使用数字作为查询条件,在这里5.0的也做个对比 8.0版本的mysql,的确是!=.<>都 ...
- Entity Framework 在MySQL中执行SQL语句,关于参数问题
在Entity Framework中添加MySQL模型,在写代码的过程中需要直接执行SQL语句. 在SQL语句中用到了@curRank := 0 这样在SQL语句中定义参数,同时还会有传入参数:ai. ...
最新文章
- 浏览器加载本地html页面,在浏览器字段中加载本地HTML文件时是否显示白屏?
- Qt Designer提升控件
- 你的IT运维管理,是否只是“看起来很美”?
- 计算机组成原理算术运算实验报告,计算机组成原理算术逻辑运算实验报告
- Java实现可视化迷宫
- leetcode python3 简单题231. Power of Two
- android4.1 l36h,索尼 L36h跌破3K 升Android 4.3机型推荐(6)-搜狐数码
- NDK配置文件Android.mk简介
- Vulkan入门(9)-渲染和显示.md
- 职工信息管理系统—C语言工程实践
- 频率超出范围黑屏Linux,显示器超出频率限制黑屏怎么解决?显示器超出频率限制黑屏解决方法...
- macbook设置充电上限
- C语言——判断一个数是否为素数(2种方法)
- 万字长文:复盘 8 年副业经历,耗时一周,我总结出了独特的「复利思维复业赚钱法」,不看后悔...
- 判断手机号所属运营商--课后程序(Python程序开发案例教程-黑马程序员编著-第11章-课后作业)
- 常用的Web前端技术有哪些?如何入门?
- 新学期可以制定目标计划并提醒的便签软件是哪款?
- 选择器和字体的设置7.22
- 阿里云ECS服务器使用入门教程(部署Web系统)
- 【Python爬虫实战】爬取2021中国大学排名(简单)
热门文章
- python networkx模块,python复杂网络处理模块networkx
- oracle symonym_oracle vs. SQL 同义词synonym 别名 alias | 学步园
- 配置TS + node 的开发环境
- Android Q 将获得大量的隐私保护功能
- 使用JUnit进行单元测试
- 《中国人工智能学会通讯》——5.15 案例速览
- 运用策略路由实现双出口数据的分流
- 我国自主研发手机操作系统 960 OS 发布
- ng-repeat根据多个字段排序
- Angular2:从AngularJS 1.x 中学到的经验