【发布时间】:2019-11-05 23:11:36
【问题描述】:
我已经创建了类似的索引
CREATE INDEX bill_open_date_idx ON bill USING btree(date(open_date));
和,
Column | Type
open_date | timestamp without time zone
并解释分析如下
案例 1
explain analyze select * from bill where open_date >=date('2018-01-01');
Seq Scan on bill (cost=0.00..345264.60 rows=24813 width=1132) (actual time=0.007..1305.730 rows=5908 loops=1)
Filter: (open_date >= '2018-01-01'::date)
Rows Removed by Filter: 3238812
Total runtime: 1306.176 ms
案例 2
explain analyze select * from bill where open_date>='2018-01-01';
Seq Scan on bill (cost=0.00..345264.60 rows=24813 width=1132) (actual time=0.006..1220.697 rows=5908 loops=1)
Filter: (open_date>= '2018-01-01 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 3238812
Total runtime: 1221.131 ms
案例 3
explain analyze select * from bill where date(open_date) >='2018-01-01';
Index Scan using idx_bill_open_date on bill (cost=0.43..11063.18 rows=22747 width=1132) (actual time=0.016..4.744 rows=5908 loops=1)
Index Cond: (date(open_date) >= '2018-01-01'::date)
Total runtime: 5.236 ms
(3 rows)
我对为什么会发生这种情况进行了足够的研究,但在任何地方都没有适当的解释。只有 case 3 正在使用我创建的索引,而不是其他索引。为什么会这样?
据我了解,case 2 搜索与列 open_date 等效的字符串,因此它不使用索引。但是为什么不是案例1。另外,如果我错了,请纠正我。
提前致谢!
编辑 1:另外,我很高兴能深入了解正在发生的事情。
以下是要点摘录 (https://gist.github.com/cobusc/5875282)
奇怪的是 PostgreSQL 重写了以前的函数 将索引创建为规范形式,但似乎没有做同样的事情 当函数在 WHERE 子句中使用时(为了匹配 索引函数)。
不过,我不清楚为什么 postgres 的开发人员没有考虑获取任何附近的匹配索引(或者我的索引在我明确地转换为 date 之前是无用的,如 case 3)。考虑到 Postgres 是高度进化和可扩展的。
【问题讨论】:
-
向问题添加执行计划时,请确保保留其格式(主要是缩进),因为这对于正确阅读计划至关重要。
-
当然!对不起! :)