PostgreSQL низкая производительность поиска по дате в поле отметки времени, проиндексированном по дате - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть таблица с полем отметки времени. Таблица содержит миллионы записей за несколько лет, и я ожидал, что запрос будет выполнен по дате.

Он не был проиндексирован по дате, поэтому я сделал это так:

CREATE INDEX dt_crea_day_idx
ON my_table (date(dt_crea at TIME ZONE 'UTC'));

После что следующий запрос занимает то же время, что и до индекса:

SELECT dt_crea::date as dt_custom, field1, field2
FROM my_table 
WHERE field1='some_value' 
AND    dt_crea::date = '2020-04-23'
ORDER BY dt_custom desc, field2

Что я могу сделать, чтобы повысить производительность такого запроса по дате?

Редактировать : аналитик спросил:

Sort  (cost=9616582.37..9616585.03 rows=1064 width=27) (actual time=290355.874..290355.906 rows=670 loops=1)
  Sort Key: field2
  Sort Method: quicksort  Memory: 77kB
  ->  Seq Scan on my_table  (cost=0.00..9616528.88 rows=1064 width=27) (actual time=72308.452..290355.232 rows=670 loops=1)
        Filter: (((field1)::text = 'some_value'::text) AND ((dt_crea)::date = '2020-04-23'::date))
        Rows Removed by Filter: 255195339
Planning time: 0.086 ms
Execution time: 290355.951 ms

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Ваш запрос должен соответствовать вашему индексу, а ваш - нет. Вы не можете запросить индекс с помощью ::date по той же причине, по которой вам не разрешили создать индекс с этим выражением.

Если вы хотите использовать эту стратегию sh, вам необходимо изменить Ваш запрос соответствует индексу, например:

SELECT dt_crea::date as dt_custom, field1, field2
FROM my_table 
WHERE field1='some_value' 
AND    date(dt_crea at TIME ZONE 'UTC') = '2020-04-23'
ORDER BY dt_custom desc, field2
0 голосов
/ 24 апреля 2020

Я бы создал обычный столбец для столбца:

CREATE INDEX dt_crea_day_idx ON my_table (dt_crea);

Этот индекс будет более универсальным, но вам нужно будет немного изменить запрос, чтобы Postgres мог использовать этот индекс:

SELECT dt_crea::date as dt_custom, field1, field2
FROM my_table 
WHERE field1='some_value' 
  AND dt_crea >= date '2020-04-23' --<< the day you are looking for
  AND dt_crea < date '2020-04-24' --<< next day
ORDER BY dt_custom desc, field2;

Этот индекс также подойдет при поиске других диапазонов, например, определенного c месяца (который ваш индекс не поддерживает):

WHERE dt_crea >= date '2020-04-01'
  AND dt_crea < date '2020-05-01'

Для для указанного c запроса (с условием = для столбца field1) индекс для обоих столбцов может быть лучше:

CREATE INDEX dt_crea_day_idx ON my_table (field1, dt_crea);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...