Выберите записи из postgres, где временная метка находится в определенном диапазоне

185
23

У меня есть столбец прибытия типа timestamp в резервировании таблиц (я использую postgres).
Как я могу выбрать все даты в этом году, например?


Я знаю, что могу сделать что-то вроде этого:


select * FROM reservations WHERE extract(year from arrival) = 2012;

Но я выполнил анализ, и похоже, что он требует сканирования последовательности.
Есть ли лучший вариант?


P.S. 1 Хм. оба пути, кажется, требуют seq. сканирования. Но тот, который у wildplasser производит результаты быстрее - почему?


cmm=# EXPLAIN ANALYZE select * FROM reservations WHERE extract(year from arrival) = 2010;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Seq Scan on vrreservations (cost=0.00..165.78 rows=14 width=4960) (actual time=0.213..4.509 rows=49 loops=1)
Filter: (date_part('year'::text, arrival) = 2010::double precision)
Total runtime: 5.615 ms
(3 rows)

cmm=# EXPLAIN ANALYZE SELECT * from reservations WHERE arrival > '2010-01-01 00:00:00' AND arrival < '2011-01-01 00:00:00';
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on reservations (cost=0.00..165.78 rows=51 width=4960) (actual time=0.126..2.491 rows=49 loops=1)
Filter: ((arrival > '2010-01-01 00:00:00'::timestamp without time zone) AND (arrival < '2011-01-01 00:00:00'::timestamp without time zone))
Total runtime: 3.144 ms
(3 rows)


** P.S. 2 - После того, как я создал индекс по столбцу прибытия, второй способ стал еще быстрее - поскольку он выглядит как запрос использует индекс. Ключ - я думаю, я буду с этим знаком. **


                                                                       QUERY PLAN                                                                        
---------------------------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on reservations (cost=4.77..101.27 rows=51 width=4960) (actual time=0.359..0.791 rows=49 loops=1)
Recheck Cond: ((arrival > '2010-01-01 00:00:00'::timestamp without time zone) AND (arrival < '2011-01-01 00:00:00'::timestamp without time zone))
-> Bitmap Index Scan on arrival_idx (cost=0.00..4.76 rows=51 width=0) (actual time=0.177..0.177 rows=49 loops=1)
Index Cond: ((arrival > '2010-01-01 00:00:00'::timestamp without time zone) AND (arrival < '2011-01-01 00:00:00'::timestamp without time zone))
Total runtime: 1.265 ms

спросил(а) 2012-09-15T19:12:00+04:00 7 лет, 9 месяцев назад
1
Решение
87

Еще одна возможность сделать PostgreSQL индексом для вашего исходного запроса - создать индекс для используемого выражения:


create index arrival_year on reservations ( extract(year from arrival) );

Это откроет PostgreSQL с возможностью использования индекса для

select * 
FROM reservations
WHERE extract(year from arrival) = 2012;

Обратите внимание, что выражение в индексе должно быть точно тем же выражением, которое используется в предложении where, чтобы сделать эту работу.

ответил(а) 2012-09-15T22:40:00+04:00 7 лет, 9 месяцев назад
218

SELECT * 
FROM reservations
WHERE arrival >= '2012-01-01'
AND arrival < '2013-01-01'
;

BTW, если распределение значений указывает на то, что сканирование индекса не будет стоить (например, если все значения указаны в 2012 году), оптимизатор все равно может выбрать полное сканирование таблицы. YMMV. Объясните, твой друг.

ответил(а) 2012-09-15T19:14:00+04:00 7 лет, 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема