传说同事写个复杂的SQL代码,跑一次需要7-10秒,
复杂如上,我也懒得去分析 IF IF IF是怎么回事了! 发现此表是分区表,后面要求加上了分区时间,以便利用到分区裁剪技术. 因为需求是查近10天来到期还款的人和金额.就是今天应该还款的人, 一般还款周期是7天. 给个10天的范围挺可以的. 结果其中一个降低到1.4秒,另外一个始终是7秒.扫描800万.
scf.request_date_time >= date_add(current_date(), INTERVAL - 10 day) and
scf.request_date_time < '2023-12-14'
纳闷! 最近后空看它的执行计划,全分区扫描,没有使用分区裁剪技术,其实也用到了一点点分区裁剪技术,我们这个表按月分区的,现在是12月份,前面3月到12月它都扫描了,后面的明年1月份之后都没扫描,毕竟是0行记录.
>= date_add(current_date(), INTERVAL - 10 day)
按ORACLE做法这个不应该啊,会直接计算表达式后去
PARTITION BY RANGE (to_days(`request_date_time`))
(PARTITION REQ_TIME_202304 VALUES LESS THAN (739006) ENGINE = InnoDB,
PARTITION REQ_TIME_202305 VALUES LESS THAN (739037) ENGINE = InnoDB,
执行计划全分区扫描,换成NOW()函数也是这样的
另外一个跑的快的也是差不多,只是KEY那项上使用了索引.
改成字符串日期值就可以分区裁剪了
换成TO_DAYS(NOW()) 是不行的
AI 的回答
在MySQL中,分区裁剪是一种优化技术,可以根据查询条件自动排除不符合条件的分区,从而提高查询性能。然而,并非所有的日期函数都支持分区裁剪。
以下是一些常见的日期函数,在使用时可能不支持分区裁剪:
函数中包含非确定性表达式:
如果日期函数中包含了非确定性表达式,例如NOW()、CURRENT_TIMESTAMP等,那么无法在查询执行之前确定具体的值,导致无法进行分区裁剪。
函数中包含用户变量或用户定义函数:
如果日期函数中包含了用户变量或用户定义函数,同样无法在查询执行之前确定具体的值,不支持分区裁剪。
函数中包含子查询:
如果日期函数中包含了子查询,也会导致无法在查询执行之前确定具体的值,无法进行分区裁剪。
在你的例子中,使用的是date_add函数,该函数可能会导致分区裁剪失效,因为它在查询执行之前无法确定具体的值。
要确保分区裁剪有效,可以尽量避免使用不支持分区裁剪的日期函数或表达式。如果需要使用这些函数或表达式,可以考虑在查询中手动指定具体的日期范围,而不是依赖于函数的计算结果。