gpt4 book ai didi

postgresql - 为什么 Postgres 不过滤我的日期范围分区?

转载 作者:行者123 更新时间:2023-11-29 11:44:33 24 4
gpt4 key购买 nike

我有一个使用 declarative partitioning 的表(w00t!)按日期范围对表进行分区 - 在我的例子中是一年。

当我查询表时 - SELECT * FROM tbl WHERE date > date '2016-01-01' ,它完全按预期工作;仅扫描包含较新数据的表。

当我使用变量或函数( CURRENT_DATENOW() 等)指定日期时,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(反正我不需要)。我加了一个以防万一,但没有用。

为什么会发生这种情况,我可以做些什么来阻止它(最好不要给简单的查询增加复杂性)?

最佳答案

感谢 JustMe 回答这个问题 - 请参阅 OP 上的评论。

问题在于 NOW()CURRENT_TIMESTAMP 何时根据 FROM 进行评估;这与您尝试在连接 ala WHERE join_table.a > from_table.b 中进行过滤时看到的问题相同。

假设今天是 1970 年 1 月 1 日,这些查询

SELECT * FROM my_stuff WHERE date > NOW()::date;
--
SELECT * FROM my_stuff WHERE date > '1970-01-01'::date;

必然会产生相同的结果集,但不一定会以相同的方式进行评估。

这就是为什么会发生这种情况,不幸的是,似乎没有一种简单的方法可以阻止它。函数似乎是最好的选择:

CREATE OR REPLACE FUNCTION myfunc()
RETURNS setof tbl
LANGUAGE 'plpgsql'
AS $$
DECLARE
n date := CURRENT_DATE - 365;
BEGIN
RETURN query EXECUTE $a$
SELECT * FROM tbl
WHERE date > $1;
$a$ using n;
END $$;

您可以通过将 RETURNS setof tbl 更改为 RETURNS setof text 并将 SELECT... 更改为 EXPLAIN SELECT.. .

关于postgresql - 为什么 Postgres 不过滤我的日期范围分区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46771736/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com