我通过以下方式在表上创建了索引:-
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
如我们所见,它在过滤行时不使用索引。我已经查看了一些stackoverflow答案,但是没有找到所需的答案。
我的pages.timestamp
列的类型为timestamp with time zone
。
过滤时,2019-05-08
会根据当前日期每天动态生成(一个单独的程序会生成它)。 text
语句中大约有12个SELECT
列,但为简单起见,我在这里写了*
。
pages
表包含每小时插入的记录,但我每天仅提取一次。目前它包含大约5000万条记录,并且每天都在增加。
如何在这里有效使用索引?我正在使用AWS RDS 9.6。
答案 0 :(得分:0)
索引表达式必须与WHERE
条件的一侧完全匹配。
您有两个选择:
使用此索引:
CREATE INDEX ON myschema.pages
((date(pages."timestamp" AT TIME ZONE 'UTC' + INTERVAL '8 hours')));
重写查询:
WHERE date(pages."timestamp" AT TIME ZONE 'UTC')
>= date(('2019-05-08'::timestamp) AT TIME ZONE 'UTC' - INTERVAL '8 hours')