将大于或小于的范围查询装换为等值查询

在生产环境,经常会遇到需要对Worker表进行多次尝试的业务,超过一定重试次数后抛弃或使用其他方式处理,在查找满足重试条件数据时,通常会使用“小于”运算符并伴随排序操作,这种场景很容易出现性能问题。

如下面查找执行次数小于最大执行次数的记录的SQL:

SELECT *
FROM worker_task
WHERE status = 3
AND execute_times < max_execute_times
LIMIT 50;

表中数据分布为:

SELECT COUNT(1),status
FROM worker_task
GROUP BY status; +----------+--------+
| COUNT(1) | status |
+----------+--------+
| 2 | 0 |
| 1 | 1 |
| 10597565 | 2 |
| 66836 | 3 |
+----------+--------+

问题分析:

上面满足status = 3条件的数据有6.6万条,由于execute_times < max_execute_times需要扫描6.6万条记录中的每一行来确定是否满足条件,因此查询需要读取全部数据并对比,严重消耗服务器IO和CPU资源,查询性能极差,且该数据量会随公司大促暴涨,很可能导致单条SQL需要扫描和对几千万上亿的数据。

优化方式:

由于每次worker尝试后,会更新execute_times的值,这种场景下,可以在表中新增一个字段表标识该记录是否需要再次重试is_over_time,并在表中增加索引idx_ status_is_over_time(status,is_over_time),查询能够通过等值查询快速定位到满足条件数据,将范围查询改为等值查找。

将IN语句的范围查询改为等值查询

查询满足条件并按照优先级和最早更新时间取前50行记录:

SELECT *
FROM t_task
WHERE status in(1,3,9)
ORDER BY priority,update_time
LIMIT 50;

问题分析:

查询需要对满足WHERE条件status in(1,3,9)的数据按照priority+update_time两个字段排序取TOP50,如果满足WHERE条件的数据量较大,那么读取这些数据并排序会消耗服务IO和CPU资源,导致性能问题。

优化方式1:

由于WHERE条件status in(1,3,9)需要分别扫描status=1 和status=3以及status=9的数据,如果能将该条件进行业务拆分,仅查询其中一个状态的数据再排序,那么可以通过符合索引(status,priority,pdate_time)来避免对大数据量数据排序,并通过LIMIT减少扫描数据量,降低IO和CPU资源。

优化后的SQL为:

SELECT *
FROM t_task
WHERE status = 1
ORDER BY priority,update_time
LIMIT 50;

优化方式2:

在促销期间,任务产生速度远高于任务处理速度,造成任务表大量数据积压,而优先级较高的任务需要优先处理,但优先级较高的任务的数据量较少,因此可以在应用程序端对数据进行分级处理,优先处理优先级高且更新时间早的任务,保证这些任务优先处理的情况下,对普通任务进行随机处理(注意避免任务被连续多次重试)。

查找优先级高的任务(使用排序):

SELECT *
FROM t_task
WHERE status in(1,3,9) and priority = 9
ORDER BY update_time
LIMIT 50;

查看优先级地的任务(不使用排序):

SELECT *
FROM t_task
WHERE status in(1,3,9) and priority <> 9
LIMIT 50;

总结:

优化就是使用合理方式降低扫描的数据量和排序的数据量。

MySQL Execution Plan--将范围扫描转换为等值查询的更多相关文章

  1. MySQL Execution Plan--执行计划中的Type列

    在一次的优化过程中,由于没有关注执行计划中type列,仅看key列来查看"使用到的索引",导致优化过程走了不少弯路. 以下面SQL为例: SELECT wave_no, SUM(I ...

  2. MySQL Execution Plan--IN查询计划

    对于IN查询,MySQL会根据当前表数据结构(索引)和数据分布(统计信息和预估)生成多种执行计划,并根据执行成本挑选出“最优执行计划”. 假设有查询 SELECT * FROM student ,,, ...

  3. Oracle SQL explain/execution Plan

    From http://blog.csdn.net/wujiandao/article/details/6621073 1. Four ways to get execution plan(anyti ...

  4. sql server 执行计划(execution plan)介绍

    大纲:目的介绍sql server 中执行计划的大致使用,当遇到查询性能瓶颈时,可以发挥用处,而且带有比较详细的学习文档和计划,阅读者可以按照我计划进行,从而达到对执行计划一个比较系统的学习. 什么是 ...

  5. Execution Plan 执行计划介绍

    后面的练习中需要下载 Demo 数据库, 有很多不同的版本, 可以根据个人需要下载.  下载地址 -http://msftdbprodsamples.codeplex.com/ 1. 什么是执行计划 ...

  6. Mysql如何避免全表扫描的方法

    在以下几种条件下,MySQL就会做全表扫描: 1>数据表是在太小了,做一次全表扫描比做索引键的查找来得快多了.当表的记录总数小于10且记录长度比较短时通常这么做. 2>没有合适用于 ON ...

  7. MySQL Execution Plan--COUNT相关测试

    COUNT全表记录 在MySQL中,相同的SQL不同的存储引擎执行计划不同: 对于MyISAM引擎,由于使用表锁进行并发控制,同一时间点多个并发线程执行相同查询获得的结果相同,且MyISAM存储引擎专 ...

  8. MySQL Execution Plan--文件排序(file sort)

    在MySQL处理ORDER BY语句时,如果查询无法利用索引的有序性,则需要额外操作对数据进行排序.在MySQL中有三种排序算法: 1.快速排序(Quick Sort),对冒泡排序的一种改进,基本思想 ...

  9. MySQL学习-MySQL内置功能_索引与慢查询

    1.索引基础 1.1 介绍 (1.)为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂 ...

随机推荐

  1. 创建、查看、删除计划任务at命令举例

    1.三天后的下午 5 点执行 /bin/ls : at 5pm + 3 days at> /bin/ls             结束按ctrl+d 查看计划任务:at -l 之后 at -c ...

  2. cube.js 最近的一些更新

    cube.js 是一个和不错的数据分析框架,最近又有了一些新的功能支持,以下是一些简单的 总结 基于web socket 的预览支持 react hooks api 支持 支持基于reecharts ...

  3. plv8 centos install steps

    install deps yum -y update yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL- ...

  4. 讲题专用——线段树——优化DP

    题目链接:http://codevs.cn/problem/3342/ 题解: 最小化最大值:二分 二分最长空题段 令f[i]表示抄第i道题所花费的最小时间 状态转移方程:f[i]=min(f[j]) ...

  5. ZROI 暑期高端峰会 A班 Day1 序列数据结构

    FBI Warning:本文包含大量人类的本质之一 CF643G 维护一个序列,可以区间赋值,求区间中出现超过 \(p\%\) 的数. 允许输出不对的数,允许重复输出,但是所有对的数都一定要输出.而且 ...

  6. ZROI 暑期高端峰会 A班 Day6 DP

    [THUPC2018]城市地铁规划 (日常讲题之前 YY--) 一眼出 \(O(n^3+nk)\) 做法. \(dp[i][j]\) 表示前 \(i\) 个点,前 \(i\) 个点度数和为 \(j\) ...

  7. [算法模板]SOS DP

    [算法模板]SOS DP 正文 SOS-DP(\(\text{Sum over Subsets}\))是用来解决这样的问题的: 其实就是子集和DP.上面每个\(F[mask]\)里面包含了\(mask ...

  8. otl odbc小计

    1. 使用odbc的时候,要注意数据库的编码与odbc配置的编码一致,不然有乱码.所以建议,表中字符编码,数据库的编码,odbc等connector的编码都是utf8,避免乱码问题 2. 安装odbc ...

  9. 牛逼哄哄的 Lambda 表达式,简洁优雅就是生产力!

    阅读本文大概需要 4 分钟. 作者:Sevenvidia https://www.zhihu.com/question/20125256/answer/324121308 什么是Lambda? 我们知 ...

  10. spark 资源动态分配

    'spark.shuffle.service.enabled': 'true', 'spark.dynamicAllocation.enabled': 'false', , , , 'spark.sq ...