SQL优化
不要让查询优化器为难
尽量缩短寻址路程
尽量减少IO
关于SQL优化的思路,一般都是使用执行计划看看是否用到了索引,主要可能有两大类情况:
对业务字段建立了二级联合索引,但是MySQL错误地觉得走主键聚族索引全表扫描效率更高,而没有走二级索引
走二级索引,但是引起了几万、几十万的回表,此时还不如利用聚簇索引进行正序或者倒序的全表扫描,配合limit n,全表扫描只需要扫到符合条件的n条就停止
案例一:千万级用户的运营查询优化-去掉半连接
案例二:亿级商品按类别/子类别查询的SQL优化-force index强制走某索引
也就是说这里的问题,
其实如果就算MySQL判断走错了索引,但是,因为只limit 10,如果能在全表扫描的过程中很快的就找到了满足条件的10条元素,那么就能很快的截断执行流程并直接返回,从而避免对整张表一扫到底,结果还没有凑齐满足条件的10条元素
案例三:十亿级评论表单商品几十万评论的深分页问题-优先主键全表扫描
案例四:千万级数据删除导致的慢查询-减少长事务
上面就是核心问题,就是每条数据都要去undo log中往前追溯,找属于自己能看到的版本对应的数据,一条两条可能速度不影响,如果上千万的数据都是这种,那么就影响很大了
案例五:跨库查询如何优化
案例六:订单量少的商户才出现慢查询
查询十月份某商户所有成功的订单,并取前10条
命中了十月份的时间索引数据有2300w条,并且这2300w的时间索引中没有商户id这个字段,就需要回表
如果该商户id下的订单非常多,那么在命中了十月份的时间索引里面,就很容易就查到了10条符合条件的数据,然后查询流程就截止并直接返回了
解决方法
- 直接去掉走强制索引,mysql就有很大的概率走merchant_id索引,而merchant_id是一个基数很大的索引字段,区分度很大
- 把时间和商户id做一个联合索引,时间如果是必选的,那么把时间放首位(但是,如果已有数据超过几千万上亿,重建联合索引耗费时间肯定巨大,所以优先考虑方法一)