慢sql优化技巧

记录一些慢sql优化技巧

  1. 在很大的数据量中获取是否有过n次xx行为。
    假设有一个很大的订单表order, 我们想知道一个用户是否有进行过5次充值。
    • 有用户id的索引
      正常可以写
    select count(1) from `order` where uid = xxxxx and status = xxxx
    
    一般来说,由于有用户id的索引,这个查询的性能不会很低。当有某一个用户有很多个订单时,这个查询就会变慢,比如id为2的用户有10000+订单,那么status=xxxx的这个条件就要对比10000+次。
    优化写法
    select 1 from `order` where uid = xxxxx and status = xxxx limit 1 offset n
    
    这样写的话我们只需要指定n的大小就可以知道用户是否有进行过n次充值。当用户订单数量很大时也是最多只进行n次条件判断即可。
  2. 获取一定时序条件下的某些数据
    假设现在需要知道一个用户在最近5天的订单
    • 有用户索引
    • 没有时间索引
      正常可以写
    select xxx from `order` where uid = xxxxx and order_time = xxxx and status = xxx
    
    由于没有时间索引,这个sql只会用到用户id的索引。
    一般来说,如果是对于订单生成时间之类的的数据,应该给时间加上索引,因为这个字段比较重要,会经常查询
    但是有可能我们要查的是用户订单异常的时间,退款的时间,一些不经常查的数据,这个字段上没有索引,想要加索引这个表又比较大,性价比很低。这里仅仅只讨论时间没有索引的情况
    由于我们限制的时间是时序的,要查询的是近5天的数据,那么我们可以简单的对历史数据统计一下。
    # id是order表的主键
    订单生成时间是xxxxxxx时, id = xxxx
    订单生成时间是xxxxxxx时, id = xxxx
    ··· ···
    
    可以按月或者按半年来分,由此来改造上述sql
    select xxx from `order` where uid = xxxx and order_time = xxxx and status = xxx and id > xxx
    
    此处的id取从上面分析的最合适的一个id,这样索引的使用就从用户id索引变成了用户id索引主键索引的index_merge状态,当这个用户有很多订单时可以少扫描很多行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值