博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
order by limit 引发的思考
阅读量:6337 次
发布时间:2019-06-22

本文共 1511 字,大约阅读时间需要 5 分钟。

SQL语句如下:

EXPLAIN SELECT id,PushData FROM UserCardPushlog WHERE status = 0   AND HANDleLock = 0 ORDER BY CreateTime LIMIT 2000

行数:2200W

status、CreateTime 均有索引

执行计划如下:

type key rows extra
index ix_UserCardPushlog_CreateTime 88469 Using where
运行时间:33s

当去掉order by、limit时执行计划如下:

type key rows extra
ref ix_UserCardPushlog_status 350140 Using where
运行时间:1s

Q1:status、CreateTime上都有索引为何执行时间相差这么多?

Q2:status 字段上的索引为什么没有被使用?

  • 单路排序与双路排序

1) 双路排序:是首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行指针信息,然后在sort buffer 中进行排序。

2) 单路排序:是一次性取出满足条件行的所有字段,然后在sort buffer中进行排序。

所有字段长度总数小于max_length_for_sort_data,则使用单路排序,否则使用双路排序。

当前服务器max_length_for_sort_data配置为1024,而表UserCardPushlog所有字段长度总数大于max_length_for_sort_data,也就是说当前SQL使用的是单路排序。

可以看到type为index,说明扫描了CreateTime字段的所有数据然后进行排序。所以很慢。

Q2 是否可以理解为如果SQL查询的是单表并且包含order by且有索引,那么就将会使用order by 字段后的索引进行排序。最后才使用where条件进行过滤?

优化方案:使用status过滤数据后再进行排序。

  1. 使用子查询过滤数据后进行排序,如下SQL仍然没有使用status的索引。

    EXPLAIN SELECT id,PushData FROM  (SELECT     id,    PushData,    CreateTime as s  FROM    UserCardPushlog   WHERE status = 0     AND HANDleLock = 0) as t ORDER BY t.s LIMIT 2000 ;
  2. 最终解决方案:强制使用索引FORCE INDEX

    EXPLAIN SELECT id,PushData FROM UserCardPushlog FORCE INDEX(ix_UserCardPushlog_status)WHERE status = 0   AND HANDleLock = 0 ORDER BY CreateTime LIMIT 2000
  3. 另一种解决方案可以参考一下:where 条件后面加上CreateTime的过滤条件,这样index就会变成range,时间也只需要15s左右。SQL如下:

    EXPLAIN SELECT id,PushData FROM UserCardPushlog WHERE status = 0   AND HANDleLock = 0  AND CreateTime >='2017-01-01'ORDER BY CreateTime LIMIT 2000

微信号:MariaDBA

QQ:3543400
未经允许禁止转载

你可能感兴趣的文章
oracle11g R2 RAC卸载grid
查看>>
ES6 结构和扩展运算符
查看>>
王利阳:电商大促 决战6.18
查看>>
kafka消息传输的事务定义
查看>>
实现LNMMP
查看>>
mysql的pid文件出现问题
查看>>
计算rem单位
查看>>
第七章 大网高级 ASA
查看>>
rsync+inotify触发式远程同步
查看>>
优秀设计师应当知道的几大UI设计原则(一)
查看>>
mongodb高级查询
查看>>
struts2.1 struts.devMode BUG解决方案
查看>>
日本法院裁定三星诉苹果专利侵权案败诉
查看>>
Windows Server 2012R2 桌面体验问题直通车
查看>>
Springboot配置文件读取报错Configuration property name 'projectUrl' is not valid:
查看>>
HTTP状态码
查看>>
今天的学习
查看>>
面试必问之JVM原理
查看>>
mysql主主同步+Keepalived
查看>>
研究音频编解码要看什么书
查看>>