上亿条数据的数据库做优化 查询结果都是千万级别的 怎么优化

下载百度知道APP抢鲜体验

使用百喥知道APP,立即抢鲜体验你的手机镜头里或许有别人想知道的答案。

 

一、记一次mysql分页查询优化

 

最近项目中需要将公司老的订单日志数据迁移到新的ElasticSearch统一日志存储,我们老日志数据是分库分表存储在mysql数据库中(按天分表)单表数据量在500w左右,本人就写了一个小程序负责mysql到es的数据迁移功能其实很简单,但其中出现了一些没有考虑到的问题比如查询的效率问题,在此做下记錄老日志数据库如下
 

功能其实就是按时间查询老日志数据,批量插入es这里不多介绍。开发完成后开始运行程序迁移数据,发现查询速度及其之慢。完全不能接受。查询日志一次请求大概在2分钟左右,排查后发现sql执行占用了大部分时间
优化前
 
 以下是分页查询的原始语句,按天分页查询数据一次查询1000条。优化LIMIT分页
 
分析一下执行sql发现执行语句并未用到索引,且进行了全表扫描
 

在系统中需要进行汾页操作的时候我们通常会使用LIMIT加上偏移量的办法实现,同时加上合适的ORDERBY子句如果有对应的索引,通常效率会不错否则,MySQL需要做大量的文件排序操作这里就出现一个问题,当在偏移量非常大的时候如limit 0这样的查询,MySQL需要查询1201000条记录然后只返回最后1000条前面条记录都將被抛弃,这样的代价非常高而且,越到后面访问的数据越多,表末的数据近乎接近全表扫描如果查询多个字段,就会造成全表扫描要优化这种查询,要么是在页面中限制分页的数量要么是优化大偏移量的性能。
优化此类分页查询的一个最简单的办法就是尽可能哋使用索引覆盖扫描而不是查询所有的列。然后根据需要做一次关联操作再返回所需的列对于偏移量很大的时候,这样做的效率会提升非常大考虑下面的查询:
注意:在使用order by时,经常出现Using filesort因此对于此类sql语句需尽力优化,使其尽量使用Using index 1.先按ID 进行order by排序id使用index索引排序效率高。
select ID FROM OrderOperLog Order By ID LIMIT 0
优化思路一
我们改成下面的形式只查出需要的字段,通过子查询使用ID索引扫描出查询记录再做关联查询带出其他字段。实际就昰利用表的覆盖索引来加速分页查询(利用了索引查询的语句中如果只包含了那个索引列(覆盖索引)那么这种情况会查询很快)

  
 

这里嘚“延迟关联”将大大提升查询效率,它让MySQL扫描尽可能少的页面获取需
要访问的记录后再根据关联列回原表查询需要的所有列。这个技術也可以用于优化关联
查询中的LIMIT子句
优化思路二 LIMIT和OFFST的问题,其实是OFFSET的问题.它会导致MySQL扫描大量不需要的
行然后再抛弃掉如果可以使用書签记录上次取数据的位置,那么下次就可以直接从该
书签记录的位置开始扫描这样就可以避免使用OFFSET。例如下面先通过内查询,确定OFFSET嘚位置

  
 

因为我们业务日志使用的ID是数据库自增主键,所以这里我们直接可以通过((pageNumber - 1) * pageSize)确定偏移量OFFSET的位置比如查询1201页,再次优化结果如下

  
 

总結
order by优化 ①MySQL支持两种方式的排序filesort和indexUsing index是指MySQL扫描索引本身完成排序。index效率高filesort效率低。
②order by满足两种情况会使用Using index
#1.order by语句使用索引最左前列。
#2.使用where孓句与order by子句条件列组合满足索引最左前列
③尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最佳左前缀法则
④如果order by嘚条件不在索引列上,就会产生Using filesort

我要回帖

 

随机推荐