Eu estava consultando assim:
SELECT count(*)
FROM orders
WHERE planned_shipping_date >= '2022-04-04'
AND planned_shipping_date < '2022-04-05'
Então me deparei com esta resposta e, como em consultas mais complicadas, tornou a consulta mais fácil de ler, reescrevi a consulta assim:
SELECT count(*)
FROM orders
WHERE planned_shipping_date <@ daterange('2022-04-04', '2022-04-05')
Acredito que sejam semanticamente idênticos, mas vejam os planos:
Aggregate (cost=76.91..76.92 rows=1 width=8) (actual time=1.066..1.068 rows=1 loops=1)
-> Index Only Scan using orders_planned_shipping_date_idx on orders (cost=0.29..69.73 rows=2872 width=0) (actual time=0.067..0.646 rows=2813 loops=1)
Index Cond: ((planned_shipping_date >= '2022-04-04'::date) AND (planned_shipping_date < '2022-04-05'::date))
Heap Fetches: 0
Aggregate (cost=2753.57..2753.58 rows=1 width=8) (actual time=18.309..18.311 rows=1 loops=1)
-> Index Only Scan using orders_planned_shipping_date_idx on orders (cost=0.29..2751.93 rows=655 width=0) (actual time=17.520..18.132 rows=2813 loops=1)
Filter: (planned_shipping_date <@ '[2022-04-04,2022-04-05)'::daterange)
Rows Removed by Filter: 128138
Heap Fetches: 0
O uso do intervalo de datas parece impedir o uso de um índice.
Preciso de um índice diferente ou não devo usar intervalos de datas como este?
Sim, suas consultas são semanticamente idênticas, mas a sintaxe também importa.
Para ser suportada por um índice, uma
WHERE
condição deve se parecer com isso:<indexed expression> <operator> <constant>
<indexed expression>
é o que foi usadoCREATE INDEX
<operator>
é um operador da classe de operadores do índice<constant>
tem que ser constante durante a varredura do índice (pelo menosSTABLE
)Além disso, o PostgreSQL conhece funções de suporte que permitem usar varreduras de índice em alguns outros casos, mas isso não se aplica aqui.
Seu problema é o operador
<@
, que não é suportado pelos índices de árvore B. Como consequência, o PostgreSQL não pode usar o índice para verificar sua condição. Portanto, continue usando sua consulta original.