带时区的 PostgreSQL 时间戳不使用索引

PostgreSQL timestamp with timezone does not use index

我按以下方式在 table 上创建了一个索引:-

CREATE INDEX pages_timestamp_idx ON mySchema.pages(date("timestamp" at time zone 'UTC'));

当我尝试 运行 查询时

EXPLAIN ANALYSE
SELECT *
FROM mySchema.pages
WHERE DATE (pages."timestamp" at TIME zone 'UTC' +INTERVAL '8 hours') >= DATE ('2019-05-08')

我得到以下输出

Seq Scan on pages  (cost=0.00..4050358.12 rows=10013919 width=1946) (actual time=215758.903..440677.734 rows=225596 loops=1)
   Filter: (date((timezone('utc'::text, "timestamp") + '08:00:00'::interval)) >= '2019-05-08'::date)
   Rows Removed by Filter: 29816159
Planning time: 0.106 ms
Execution time: 440721.718 ms

正如我们所见,它在过滤行时没有使用索引。我浏览了几个 Whosebug 的答案,但没有找到所需的答案。

我的 pages.timestamp 列的类型是 timestamp with time zone

过滤时,2019-05-08 每天根据当前日期动态生成(由单独的程序生成)。我在 SELECT 语句中有大约 12 text 列,但为了简单起见,我在这里写了 *

pages table 包含按小时插入的记录,但我每天只提取一次。目前它包含大约 5000 万条记录,并且每天都在增加。

如何有效地使用这里的索引?我正在使用 AWS RDS 9.6。

索引表达式必须与 WHERE 条件的一侧完全匹配。

您有两个选择:

  1. 使用这个索引:

    CREATE INDEX ON myschema.pages
       ((date(pages."timestamp" AT TIME ZONE 'UTC' + INTERVAL '8 hours')));
    
  2. 重写查询:

    WHERE date(pages."timestamp" AT TIME ZONE 'UTC')
          >= date(('2019-05-08'::timestamp) AT TIME ZONE 'UTC' - INTERVAL '8 hours')