更新时间:2024-07-01 GMT+08:00

未分区剪枝导致SQL查询慢

问题现象

SQL语句查询慢,查询的分区表总共185亿条数据,查询条件中没有涉及分区键。

1
2
SELECT passtime FROM table where passtime<'2020-02-19 15:28:14' and passtime>'2020-02-18 15:28:37' order by passtime desc limit 10; 
SELECT max(passtime) FROM table where passtime<'2020-02-19 15:28:14' and passtime>'2020-02-18 15:28:37'; 

列存表,分区键为createtime,哈希分布键为motorvehicleid。

原因分析

慢SQL过滤条件中未涉及分区字段,导致执行计划未分区剪枝,进行了全表扫描,性能严重劣化。

分析过程

  1. 和用户确认部分业务慢,执行慢的业务中都涉及到了同一张表tb_motor_vehicle。
  2. 收集几个典型的慢SQL语句,分别打印执行计划。从执行计划中可以看出来,两条SQL的耗时都集中在Partitioned CStore Scan on public.tb_motor_vehicle列存表的分区扫描上。

  3. 已确认该表的分区键为createtime,而涉及的SQL中无任何createtime的筛选和过滤条件,基本可以确认是由于慢SQL的计划没有走分区剪枝,导致了全表扫描,对于185亿条数据量的表,全表扫描性能会很差。

处理方法

在慢SQL的过滤条件中增加分区筛选条件,避免走全表扫描。

优化后的SQL和执行计划如下,性能从十几分钟,优化到了12秒左右,性能有明显提升。
1
SELECT passtime FROM tb_motor_vehicle WHERE createtime > '2020-02-19 00:00:00' AND createtime < '2020-02-20 00:00:00' AND passtime > '2020-02-19 00:00:00' AND passtime < '2020-02-20 00:00:00' ORDER BY passtime DESC LIMIT 10000;