我有一个表产品
Product(id BIGINT,
... Some more columns here
expired DATE);
我想在过期的字段上创建索引以便更快地检索。
我的where子句的大部分时间是
...
WHERE (expired IS NULL OR expired > now());
请问您能建议哪种指数更适合我。
当我为上述查询执行explain analyze时
EXPLAIN ANALYZE
SELECT 1
FROM product
WHERE (expired IS NULL) OR (expired > now());
它给了我以下结果。其中没有使用我创建的索引。
Seq Scan on product (cost=0.00..190711.22 rows=5711449 width=0) (actual time=0.009..8653.380 rows=7163105 loops=1)
Filter: ((expired IS NULL) OR (expired > now()))
Rows Removed by Filter: 43043
Planning time: 0.117 ms
Execution time: 15679.478 ms
(5 rows)
我猜这是因为“OR”条件。我试图创建功能基础索引,但它给了我以下错误
ERROR: functions in index expression must be marked IMMUTABLE
我们还有其他替代方法吗?
答案 0 :(得分:1)
默认的B树索引可能是最合适的;哈希索引只处理“等于”比较,而GiST和GIN索引适用于您正在使用的更复杂的数据类型:
https://www.postgresql.org/docs/current/static/indexes-types.html
实际上B树是默认的,所以你需要做的就是:
CREATE INDEX Products_expired_idx ON TABLE Products (expired)
答案 1 :(得分:1)
您应该将WHERE
子句更改为:
... WHERE COALESCE(expired, DATE 'infinity') > current_date;
这相当于您的查询,但现在您可以使用以下索引:
CREATE INDEX ON product (COALESCE(expired, DATE 'infinity'));