上亿级的表-TiDB列表查询优化

效果

优化之前,查询近一个月接口响应时间:20秒,优化之后,接口响应时间:3-4秒

背景

运维监控TiBD数据库运行情况,发现某些时段CPU过高,然后查看慢SQL日志,把慢SQL反馈给开发人员。SQL的业务背景,分页查询订单,并把符合查询条件的金额等数值进行统计

问题分析

1、该接口主要是分页查询+业务统计查询,分页查询用了插件,其中插件中的count()查询可在业务统计查询中所得
2、分页SQL查询慢,尝试能否优化

优化方案

1、取消分页插件,手动分页
2、从统计SQL中获取总条数(分页所需的数据),减少一次SQL查询
3、改造分页SQL,先根据查询条件得到id集合,再根据id集合查询最终所需的数据

SQL优化

优化前的SQL(提供参考)

分页

SELECT o.id                              AS id,
       o.order_id                        AS orderId,
       o.user_id                         AS userId,
       o.merchant_id                     AS merchantId,
       o.amount                          AS amount
FROM order o
<include refid="order_where_inside"/>
ORDER BY po.create_time DESC
LIMIT #{dto.limitBegin}, #{dto.pageSize}

统计

SELECT
/*+ read_from_storage(tiflash[o]) */
o.merchant_id AS merchantId,
sum(o.amount) AS amount
FROM
order o
<include refid="order_where_inside"/>
GROUP BY merchant_id

优化后的SQL(提供参考)

分页

SELECT o.id
FROM order o
<include refid="order_where_inside"/>
ORDER BY o.create_time DESC
LIMIT #{dto.limitBegin}, #{dto.pageSize}
		
SELECT o.id                              AS id,
       o.order_id                        AS orderId,
       o.user_id                         AS userId,
       o.merchant_id                     AS merchantId,
       o.amount                          AS amount
FROM order o
WHERE o.id IN
<foreach collection="ids" item="item" open="(" close=")" separator=",">
    #{item}
</foreach>
ORDER BY o.create_time DESC

统计

SELECT
/*+ read_from_storage(tiflash[o]) */
o.merchant_id AS merchantId,
sum(o.amount) AS amount,
...
-- 分页所用的count
count(o.id) AS totalOrder
FROM
order o
<include refid="order_where_inside"/>
GROUP BY merchant_id

尝试过优化失败的方案

查询条件得到id集合当做子查询,整合成一条SQL,执行效率有点出乎意料,优化器反而没怎么使用上索引,导致效率低下

总结

1、SQL上线前需要看看执行效率,判断有没有优化的空间
2、分页插件需好用,也需要根据实际业务判断是否有影响
3、可以根据业务场景建立多个从库,比如用户版读库,商家版读库,不同的库用不同的索引

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值