sql优化问题

SELECT orders.GUIZI_NO AS cabNo, CAST(SUM(ordinPost.amount) AS DECIMAL(14,2)) AS orderMoney
FROM
( 
  SELECT order_water_code, amount
  FROM wallet_pay_post_record t
  WHERE t.create_time >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
  AND t.`status` = 1 
) ordinPost 
INNER JOIN guizi_order orders ON ordinPost.order_water_code = orders.TRADE_WATER_NO
GROUP BY orders.GUIZI_NO
HAVING orderMoney < '200.00'

wallet_pay_post_record 这个表有1亿多条数据,查询统计很慢,问了create_time加索引好像也提高不了多少速度。

执行计划
图片描述

阅读 3.5k
6 个回答

sql逻辑上进行优化
1 在内层先对wallet_pay_post_record 表根据order_water_code字段进行group by操作,减少INNER JOIN的数据量
2 如果wallet_pay_post_record和guizi_order 是多对一的关系,amount<200的条件可以移到内层先处理。

  SELECT order_water_code, sum(amount) as amount
  FROM wallet_pay_post_record t
  WHERE t.create_time >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
  AND t.`status` = 1 
  and t.amount < 200
  group by order_water_code
  having amount < 200

单表1亿,分表是应该的
另外单表1亿,你只是取最近30天的记录,30天有多少记录呢?占总表十分之一百分之一的话加索引效率肯定会好的
索引的话,如果条件固定可以复合索引(status,create_time),否则就一个create_time单列索引吧
最后orders.TRADE_WATER_NO这个肯定有索引的吧。。

优化建议:不要在sql里面进行运算

用空间换时间,可以分开写多条sql语句

1.修改DATE_SUB,使用create_time>='...' and create_time <='...'。
2.orderMoney < '200.00' 改成 orderMoney < 200.00。
最好把explain信息发出来一下。

统计交给程序做,别用数据库函数

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题