我是这样查询的:
SELECT count(*)
FROM orders
WHERE planned_shipping_date >= '2022-04-04'
AND planned_shipping_date < '2022-04-05'
然后我遇到了这个答案,因为在更复杂的查询中它使查询更容易阅读,我重写了这样的查询:
SELECT count(*)
FROM orders
WHERE planned_shipping_date <@ daterange('2022-04-04', '2022-04-05')
我相信它们在语义上是相同的,但看看这些计划:
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
日期范围的使用似乎排除了索引的使用。
我需要不同的索引还是不应该使用这样的日期范围?
是的,您的查询在语义上是相同的,但语法也很重要。
为了得到索引的支持,
WHERE
条件必须如下所示:<indexed expression> <operator> <constant>
<indexed expression>
是什么用于CREATE INDEX
<operator>
是索引的运算符类中的运算符<constant>
在索引扫描期间必须保持不变(至少STABLE
)此外,PostgreSQL 知道允许它在某些其他情况下使用索引扫描的支持函数,但这并不适用于此。
您的问题是 operator
<@
,它不受 B-tree 索引的支持。因此,PostgreSQL 无法使用索引来检查您的状况。因此,请继续使用您的原始查询。