【发布时间】:2017-10-16 13:38:52
【问题描述】:
我有一张表,它使用declarative partitioning (w00t!) 按日期范围对表进行分区——在我的例子中是一年。
当我查询表 - SELECT * FROM tbl WHERE date > date '2016-01-01' 时,它完全按预期工作;只扫描包含较新数据的表。
当我使用变量或函数(CURRENT_DATE、NOW() 等)指定日期时,EXPLAIN 表示它会扫描每个分区。
按预期工作的事情:
SELECT * FROM tbl WHERE date > date '2016-01-01'
--
SELECT * FROM tbl WHERE date > '2016-01-01'::date
不必要地扫描所有分区的东西:
SELECT * FROM tbl WHERE date > CURRENT_DATE
--
SELECT * FROM tbl WHERE date > NOW()
--
SELECT * FROM tbl WHERE date > (NOW() - 365)::date
--
SELECT * FROM tbl WHERE date > (SELECT (NOW()::date - 365)::date AS d)
-- Even CTEs are no dice:
WITH a AS (SELECT CURRENT_DATE AS d)
SELECT * FROM tbl, a WHERE date > a.d
-- Same with JOINs
SELECT w.*
FROM (CURRENT_DATE - 365 as d) a
LEFT JOIN wtf w ON w.date > a.d
..等
我在使用其他比较运算符时得到相同的行为 - =、< 等。
文档说我在现场不需要 idx(反正我不需要)。我添加了一个以防万一,但它没有帮助。
为什么会发生这种情况,我可以做些什么来阻止它(最好不要给简单的查询增加复杂性)?
【问题讨论】:
-
请Edit您的问题并为有问题的表(包括所有索引)添加
create table语句以及使用explain (analyze, verbose)生成的执行计划。 Formatted text 请no screen shots -
那是因为 planner 直到执行才知道 now() 的输出。
-
谢谢@JustMe - 你能把这个作为答案发布,这样我就可以接受它并删除不必要的 SQL 和 EXPLAIN 的输出,这样也可以帮助其他人?
标签: postgresql database-partitioning