mysql 对索引limit_【业务学习】关于MySQL order by limit 走错索引的探讨
Grape
描述
今天在跑脚本的时候发现了几条慢查询,根据之前的经验实属不应该,后来经过查找资料和分析出来结果,在这里简单记录一下。
首先,我的sql是这个样子:
select `id` from `xxx` force index(idx_d_t) where `date` = '2019-09-11' AND `time_flag` < '20190911220000' order by id asc;
索引是下边这个样子:
KEY `inx_t_d` (`date`,`time_flag`);
按照我之前的理解这条sql是可以走这个索引的,但是他没有,他选择了主键索引。
分析
看到这是个慢查询,我起手一个explain,结果如下:
看到这个结果我肯定不服啊,为什么是走的主键索引,因此开始了百度谷歌之旅。
刚开始我找到了一个自认为比较正确的方法,在某度上找了一篇文章说orderby之前有范围查找的会走orderby之后的索引,反之走orderby之前的索引,我试了一下,哎,不错,我把范围查询改成了等值查询,是走了我的索引了,但是我看了一眼行数,一脸懵逼,为什么这么多行?这不是我想要的
然后我profiling(大家可以自行百度)查了下时间,发现Creating sort index这哥们占用了九成的时间,这时候我敏锐的察觉到了这个排序有问题,(该吃饭了)不行,继续查!
继续查,上某哥,哎你别说,某哥大法还是好,终于找到了一个大佬的分析,具体是什么原因呢?
首次,我强制走我的联合索引看下情况:
看到上图会发现有个差别就是Using filesort这玩意儿,这玩意儿是个什么东西呢?简单的说filesort 是通过相应的排序算法将取得的数据在内存中进行排序。俗话说有对比才有伤害,抓到敌人的小辫子就接近了胜利,我们继续看。
fliesort有两种排序方式:
双路排序:首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行指针信息,然后在 sort buffer 中进行排序。
单路排序:是一次性取出满足条件行的所有字段,然后在 sort buffer 中进行排序。
什么时候用到这两种呢?MySQL 主要通过比较所设定的系统参数 max_length_for_sort_data 的大小和 Query 语句所取出的字段类型大小总和来判定需要使用哪一种排序算法。如果 max_length_for_sort_data 更大,则使用第二种优化后的算法,反之使用第一种算法。很显然应该尽可能让 MySQL 选择使用第二种单路算法来进行排序。这样可以减少大量的随机 IO 操作,很大幅度地提高排序工作的效率。
上文分析的排序时间过长很可能就和这个有关系了,继续查资料分析,问题的关键就在于为什么会filesort。
结论
在执行语句的时候,因为数据量较大,MySQL优化器认为走联合索引不好,默认选择了第一个更慢的执行计划,它的理由是走主键索引不需要内存排序,候选的 idx_d_t被淘汰。优化器认为主键索引不用排序比联合索引要好,所以导致了这种情况,
那我们该怎么做,在这里我只列出我的解决方法,他认为主键更好,那么我们就给他更好的,我们更改idx_d_t这个索引,由date,time_flag改成,id,date,time_flag,这样就解决问题了。
如图:
最后总结一下,就是优化器会尽量避免走file_sort,这样可能会导致一些问题。
以上分析若有差错,还望不吝指教!感谢。
参考文章:
mysql 对索引limit_【业务学习】关于MySQL order by limit 走错索引的探讨相关推荐
- mysql 优先队列_深入浅出 MySQL 优先队列(你一定会踩到的order by limit 问题)
英语和算法是程序员的两条腿 本文适用于 MySQL 5.6 及以上版本 0.先抛问题 假设字段category无索引且有重复值,order by category 和limit组合使用的结果会和预期不 ...
- mysql外部排序_深入浅出MySQL优先队列(你一定会踩到的order by limit 问题)
0.先抛问题 假设字段category无索引且有重复值,order by category 和 limit 组合使用的结果会和预期不符. 问题复现: 表结构(就是两个字段) CREATE TABLE ...
- SQL数据分析:sqlzoo官网学习select,where,order by,limit,聚合函数,having,常用函数,窗口函数,表链接,子查询
SQL数据分析: 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,oracle,尤其sql要学,当然,像很多金 ...
- java对mysql读写权限设置_Java学习笔记——MySQL开放3306接口与设置用户权限
系统Ubuntu16.04 LTS 1.开放3306端口 查看端口状态: netstat -an|grep 3306 tcp 0 0 127.0.0.1:3306 ...
- mysql php 增删数据,php学习之mysql数据的增删改查
1.插入数据 语句:insert into 表名 [(字段1,字段2,字段3,-.)] values (值1,值2,值3,-); 单行插入数据 省略字段名,这种写法后面的值必须要完整,有多少字段就要插 ...
- mysql explain 为空_车祸现场!我的MySQL千万级数据表选错索引了!
最近在线上环境遇到了一次SQL慢查询引发的数据库故障,影响线上业务.经过排查后,确定原因是:SQL在执行时,MySQL优化器选择了错误的索引(不应该说是"错误",而是选择了实际执行 ...
- MySQL选错索引导致的线上慢查询事故复盘
前言 又和大家见面了!又两周过去了,我的云笔记里又多了几篇写了一半的文章草稿.有的是因为质量没有达到预期还准备再加点内容,有的则完全是一个灵感而已,内容完全木有.羡慕很多大佬们,一周能产出五六篇文章, ...
- order by limit 造成优化器选择索引错误
1.order by limit 选错索引示例 在日常工作中,经常发现一些简单的查询语句因为加了 order by limit 造成优化器选择索引错误.例如如下sql(此处就不造数据了,只是列出一个s ...
- 在mysql中unique唯一索引的作用_MySQL_MySQL中的唯一索引的简单学习教程,mysql 唯一索引UNIQUE一般用于不 - phpStudy...
MySQL中的唯一索引的简单学习教程 mysql 唯一索引UNIQUE一般用于不重复数据字段了我们经常会在数据表中的id设置为唯一索引UNIQUE,下面我来介绍如何在mysql中使用唯一索引UNIQU ...
最新文章
- php7.0源码包下载,PHPDisk 7.0 V-Core系列发布,源码下载[更新20140821]
- vilatile 深入理解java虚拟机_《深入理解Java虚拟机》笔记 第十二章 volatile变量
- java中的Static、final、Static final各种用法
- 抹机王怎么一键新机_[电脑] [第六届机王争霸赛]水冷组——十年 by ilas 完工
- mysql创建用户删除权限_mysql 用户创建、授权及删除、取消权限操作
- 亲测可用|奥维互动地图加载谷歌地图等图源的方法
- 一个开源的音频分离深度学习项目
- 日骗上百的淘宝网赚项目骗局
- 在Word文档里如何快速返回目录页-Office学习
- 对Kindle进行可用性研究
- java根据入参不同调不同方法_java根据传入参数不同调用不同的方法,求高手支妙招!...
- 黑灰对比可以为高大上网站风格代言
- 5G消息是什么?RCS又是什么?让我们一探究竟
- 京东财报图解:年营收9516亿增28% 全渠道取得阶段性进展
- SpringBoot使用Freemarker导出word模板(OpenXML)
- c语言输入三个身高输出最高,输入两个人的身高,计算并输出他们的平均身高.(身高以米为单位,最后结果保留两位小数)...
- 2015计算机职称水平考试,2015计算机职称等级考试技巧汇总.doc
- 蓝桥杯 历届试题 高僧斗法
- linux类mac桌面,elementary OS:媲美 Mac OS X 的 Linux 漂亮桌面環境
- windows系统命令