我有一个包含两个日期的表,例如dateTo和dateFrom,我想在查询和gist索引中使用daterange方法,但它似乎不起作用。该表看起来像:
CREATE TABLE test (
id bigeserial,
begin_date date,
end_date date
);
CREATE INDEX "idx1"
ON test
USING gist (daterange(begin_date, end_date));
然后,当我尝试解释如下的查询时:
SELECT t.*
FROM test t
WHERE daterange(t.begin_date,t.end_date,'[]') && daterange('2015-12-30 00:00:00.0','2016-10-28 00:00:00.0','[]')
我得到了Seq Scan。
这对gist索引的使用是错误的,还是这种情况不可行?
答案 0 :(得分:3)
表达式daterange(begin_date, end_date)
上有索引,但您使用daterange(begin_date, end_date, '[]') && ...
查询表格。 PostgreSQL不会做你的数学而不是数学。要重新定义您的问题,就好像您正在为(int_col + 2)
编制索引并查询WHERE int_col + 1 > 2
。因为这两个表达式不同,所以索引不会在任何情况下使用。但正如您所看到的,您可以进行数学运算(即重新表达公式)。
您需要:
CREATE INDEX idx1 ON test USING gist (daterange(begin_date, end_date, '[]'));
或者:
CREATE INDEX idx2 ON test USING gist (daterange(begin_date, end_date + 1));
注意:它们都会创建一个包含end_date
的范围。后者使用daterange
离散的事实。
对上面的每个索引使用以下谓词:
WHERE daterange(begin_date, end_date, '[]') && daterange(?, ?, ?)
或者:
WHERE daterange(begin_date, end_date + 1) && daterange(?, ?, ?)
注意:&&
右侧侧的范围构造函数的第三个参数无关紧要(在索引使用的上下文中)。