大数据分页查询 or 导出 慢sql治理

背景

当前日增数据量将近千万,条件查询虽然做了联合索引,但扫描行数仍有30w左右,会出现超一秒的慢sql

缺陷

原因分析
1、联合索引首个未添加分库分表键
2、当前分库分表键是根据业务选择,数据分布不均匀
3、根据时间查询,跨度较大,扫描行多

要求

1、由于数据量太大,添加索引困难,并且查询场景为web页面,频率较低,为不影响线上业务,不去修改索引(存在4种不同时间查询,修改要加4个)
2、由于业务需要,时间查询跨度为7天,为不影响使用,不缩短查询时间范围

优化方案

1、时间拆分查询
主要的优化方案,也是接下来要讲的方案
2、count 加缓存
页面分页查询,多次count影响性能,虽然不能解决慢sql问题,但对查询性能有部分提升
3、部分走强制索引
页面允许使用单号查询,单号为唯一键,但mysql查询仍然走了时间索引,这部分查询强制走单号索引

时间拆分查询存在问题

在对count进行拆分时,只需要对时间按天 or 小时拆分,对拆分后多次count,求和即可,但是页面的要求是分业查询,如何实现时间拆分的同时,可以实现分页查询?

方案说明

由于数据查询根据时间按天拆分,那么拆分后每次查询需要对sql中偏移量和查询条数进行重新计算

例如: 查询签收时间在某6天内的数据,分页查询,每页50条,查询第n页
需要查询的数据为 select * from [表A] [条件] limit 50(n-1),50
例如,需要拆分的数据分布如下 day1下符合数据30条,day2下100条…
大数据分页查询 or 导出 慢sql治理

思路:从day1开始获取数据,到day6结束,如果提前获取到数据,则直接返回
n=3时,即第3页数据查询 limit 100,50 查询的数据为第101条开始,到150条结束 [101,150]
第一次count ,得到day1 数据 30条,数据范围 [1,30],不符合
第二次count ,得到day2 数据 100条,数据范围 [31,130],部分符合,符合数据范围[101,130] ,
根据符合范围,计算偏移量和查询条数
需要查询的数据为 select * from [表A] [条件 时间=day2] limit A,B
A=101 -1
B= 130 - A = 30
得到查询数据30条,说明需要继续查询20条
第三次count ,得到day3 数据 30条,数据范围 [131,160],部分符合,符合数据范围[131,150] ,
根据符合范围,计算偏移量和查询条数
需要查询的数据为 select * from [表A] [条件 时间=day3] limit A,B
A=131 -1
B= 150 - A = 20
得到查询数据20条,加上day2查询的30条,共50条,查询结束 END

方案优点

页面是分页查询,条数最大50条,实际总数据量2-3万,用户只会查询前几页,根据时间拆分查询时,查询第1天数据就完全满足,相对原来只是多了一次count,并且扫描行大大降低,对查询时间影响较小

方案缺点

原来一次查询数据库,优化后需要多次count和数据查询,增加了查询时间
注:实际发现时间确实有增加,但是增加不多