性能优化案例-SQL优化

最近刚做了系统迁移,需要将老系统的数据迁移到新的系统中,老系统中是分了100张表,表的数据量分配不均匀,有些表有40G左右的数据,而有些表的数据又比较少。

刚开始处理的方式是,先获取该表数据的总量,然后进行分页处理,迁移的sql如下:
第一步:
`

select count(1) from some_table where type_id = #type_id#;

`

第二步:

`
select * from some_table where type_id = #type_id# limit #offset#,#pageSize#;
`

如果对于小名单数量在100万以内的,这个sql的性能还是挺能满足的,但是当越到后面的名单的时候,SQL性能越来越差。

原因

limit有两个参数,第一个参数是offset,第二个参数是取的数据量。当offset很大时,mysql需要扫描从头到offset的数据量,这个时间会随着offset越大而越大。

第一次优化

  1. 使用id分区. 先获取最小的id,然后按照id进行过滤,取最近100条。然后下次循环的时候,重新设置id值。
  2. 再次循环获取下一个100条数据。

select min(id) from some_table where type_id = #type_id#;
`select * from some_table where type_id = #type_id# and id > #min# order by id asc limit #pageSize#;
`

  1. 通过上面的优化后,在100万的名单只需要10分钟就可以查询完毕,这个优化解决了大部分的名单迁移,但是在迁移到一些表的数据仍然不行,因为增加id的排序,导致每次的排序,需要做几亿的数据的扫描:

3_

第二次优化

因为我们的目标就是将所有的数据全部读出来,所以可以先把min和max的id取出来,然后通过id增加固定步调的方式来进行处理。

select min(id) from some_table where type_id = #typeId#

select max(id) from some_table where type_id = #typeId#

伪代码:
`
int pageSize = 500;
for(int i = minId; i<= maxId; i+=pageSize){

           select * from some_table where type_id =#type_id# where id between i and i+ pageSize;

}
`
由于没有排序的操作,所以每次的取的数据范围非常小,通过执行计划也是可以看出:

FireShot_Capture_iDB_3_0_alibaba_inc_com_https___idb_alibaba_inc_com_

总结

sql的写法不同,执行计划完全不同,作为开发人员,不能只单纯的满足业务功能就可以了,而是要想想自己写得sql会怎么执行,会走那些索引,数据量大得情况下会怎么样。并且要善于用一些工具帮助自己分析,(比如idb上得执行计划的功能就非常棒), 共勉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值