Временная метка PostgreSQL с часовым поясом не использует индекс - PullRequest
2 голосов
/ 10 мая 2019

Я создал индекс для таблицы следующим образом: -

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генерируется динамически каждый день, исходя из текущей даты (ее генерирует отдельная программа).У меня около 12 text столбцов в операторе SELECT, но просто для простоты я написал здесь *.

Таблица pages содержит записи, которые вставляются ежечасно, но яизвлекайте его только один раз в день.В настоящее время он содержит около 50 миллионов записей и увеличивается с каждым днем.

Как эффективно использовать индекс здесь?Я использую AWS RDS 9.6.

1 Ответ

0 голосов
/ 10 мая 2019

Индексированное выражение должно точно соответствовать одной стороне условия 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')
    
...