Как автоматически извлечь или индексировать день из отметки времени в Postgres? - PullRequest
0 голосов
/ 12 октября 2018

У нас есть таблица Postgres с полем отметки времени created_at.На регулярной основе нам нужно находить все записи с полем дня created_at, представляющим собой определенное число.

Мы можем выполнить запрос, подобный

select * from table where extract(day from created_at) = 3;

Я подозреваю, что это ненеэффективно, то есть выполняет полное сканирование таблицы.Если да, могу ли я как-то создать индекс, чтобы сделать вышеописанное эффективным?

Если это невозможно, мы можем создать отдельный столбец с именем created_at_day и создать для него индекс.

Итакмы можем просто выполнить запрос как

select * from table where created_at_day = 3;

Допустим, created_at можно обновить.Всякий раз, когда это происходит, created_at_day также следует обновлять.

Предоставляет ли Postgres какую-либо поддержку для автоматической синхронизации created_at_day с created_at?Если да, то как?

Конечно, это можно сделать в логике приложения.Поэтому, когда created_at создается или обновляется, мы обновляем столбец created_at_day.Но просто интересно, есть ли более простой, автоматизированный способ сделать это.

Спасибо

1 Ответ

0 голосов
/ 12 октября 2018

Вы можете создать индекс для extract(day from created_at)

Чтобы увидеть разницу:

Создать таблицу

knayak=# create table t as select i ,now()::timestamp + interval '1 days' * i as created_at from generate_series(1,10000) as i;
SELECT 10000

Создайте нормальный индекс для созданного_

knayak=# create index ind_created_at on t(created_at);
CREATE INDEX

knayak=# explain analyze select * from t where extract(day from created_at) = 3;
                                           QUERY PLAN
-------------------------------------------------------------------------------------------------
 Seq Scan on t  (cost=0.00..205.00 rows=50 width=12) (actual time=1.049..6.020 rows=328 loops=1)
   Filter: (date_part('day'::text, created_at) = '3'::double precision)
   Rows Removed by Filter: 9672
 Planning time: 0.392 ms
 Execution time: 6.070 ms
(5 rows)

Создание индекса с извлечением

knayak=# drop index ind_created_at;
DROP INDEX
knayak=# create index ind_created_at on t( extract(day from created_at) );
CREATE INDEX
knayak=# explain analyze select * from t where extract(day from created_at) = 3;
                                                        QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=4.67..61.66 rows=50 width=12) (actual time=0.110..0.260 rows=328 loops=1)
   Recheck Cond: (date_part('day'::text, created_at) = '3'::double precision)
   Heap Blocks: exact=54
   ->  Bitmap Index Scan on ind_created_at  (cost=0.00..4.66 rows=50 width=0) (actual time=0.093..0.093 rows=328 loops=1)
         Index Cond: (date_part('day'::text, created_at) = '3'::double precision)
 Planning time: 0.316 ms
 Execution time: 0.314 ms
(7 rows)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...