Необходимо иметь индекс только на created_at::date
.Квалификация where
не является необходимой и будет делать странные вещи при изменении current_timestamp
.Индекс B-дерева Postgres по умолчанию может обрабатывать запросы на равенство и диапазон.
Обязательно используйте дополнительные скобки.
test=> create index my_table_created_at_date on my_table((created_at::date));
CREATE INDEX
test=> analyze my_table;
ANALYZE
test=> explain select * from my_table WHERE date(created_at) = date(current_timestamp) - INTERVAL '1 day';
QUERY PLAN
-----------------------------------------------------------------------------------------
Index Scan using my_table_created_at_date on my_table (cost=0.29..8.43 rows=2 width=8)
Index Cond: (date(created_at) = (date(CURRENT_TIMESTAMP) - '1 day'::interval))
Также обязательно указывайте индекспросто created_at
, чтобы охватить другие не датированные запросы.
test=> create index my_table_created_at on my_table(created_at);
CREATE INDEX
test=> analyze my_table ;
ANALYZE
test=> explain select * from my_table WHERE created_at between (current_timestamp - INTERVAL '1 day') and current_timestamp;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Index Only Scan using my_table_created_at on my_table (cost=0.29..4.39 rows=5 width=8)
Index Cond: ((created_at >= (CURRENT_TIMESTAMP - '1 day'::interval)) AND (created_at <= CURRENT_TIMESTAMP))