PostgreSQL gist索引

时间:2017-04-18 15:44:11

标签: postgresql

我有一个包含两个日期的表,例如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索引的使用是错误的,还是这种情况不可行?

1 个答案:

答案 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(?, ?, ?)

注意&& 右侧侧的范围构造函数的第三个参数无关紧要(在索引使用的上下文中)。