【问题标题】:PostgreSQL gist indexPostgreSQL 要点索引
【发布时间】:2017-04-18 15:44:11
【问题描述】:

我有一个表,其中包含两个日期,例如 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','[]')

我得到一个序列扫描。

这种 gist 索引的使用是错误的,还是这种情况不可行?

【问题讨论】:

  • 为什么不在 begin_date 和 end_date 上使用 B 树多列索引?我认为如果您的行数很少,您可能会进行 seq 扫描。也许您需要足够的数据来对您的实施进行压力测试。
  • 您正在尝试使用带有错误表达式的表达式索引。您在索引中有daterange(begin_date, end_date),但您使用daterange(begin_date, end_date, '[]') 查询表(注意第三个参数)。
  • @andrei-macarie 我正在使用 gist 索引,因为 b-tree 不支持范围运算符。
  • @pozs 这不是真的。该索引适用于两者。
  • 您需要使用 seqscan 提供解释分析,还需要提供 set enable_seqscan = 0; 和相同的解释分析。

标签: postgresql


【解决方案1】:

您在表达式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(?, ?, ?)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 2010-09-28
    相关资源
    最近更新 更多