Sql 无索引仅扫描索引中的日期转换
我创建以下表和索引:Sql 无索引仅扫描索引中的日期转换,sql,postgresql,Sql,Postgresql,我创建以下表和索引: CREATE TABLE test ( id bigint, d timestamp without time zone ); CREATE INDEX f_date4 ON public.test USING btree (date(d), id); CREATE INDEX f_date5 ON public.test USING btree (id, date(d)); 我用数据填充表格并使用以下查询: SELECT id, date
CREATE TABLE test
(
id bigint,
d timestamp without time zone
);
CREATE INDEX f_date4
ON public.test
USING btree
(date(d), id);
CREATE INDEX f_date5
ON public.test
USING btree
(id, date(d));
我用数据填充表格并使用以下查询:
SELECT id, date(d)
FROM test
WHERE date(d) > '2019-09-20'::date;
EXPLAIN
显示f_date4索引是在条件d>'2019-09-20':date
下使用的,但我无法仅扫描索引。可能的原因是什么,为什么会发生这种情况,以及如何避免这种情况
执行计划:
Index Scan using f_date4 on test (cost=0.06..0.07 rows=1 width=12) (actual time=0.005..0.005 rows=0 loops=1)
Index Cond: (date(d) > '2019-01-20'::date)
Buffers: shared hit=2
Planning time: 0.131 ms
Execution time: 0.025 ms
我使用postgresql 10.6
提前谢谢 正如人们所说:
然而,PostgreSQL的规划者目前对此类案例并不十分精明
总而言之,计划者的一部分认为它需要“d”来计算日期(d)
,即使另一部分意识到它已经有了日期(d)。让这两个部分进行沟通并不容易
您可以构建索引
(日期(d),id,d)
来解决这个问题。完整时间戳上的索引与截断时间戳上的索引具有相同的用途
结果查询计划:
@一匹没有名字的马我已经编辑了我的问题并添加了一个计划。没有更多的索引。这是一个测试表,是为了提问而创建的。它有1000行。同样的情况也发生在大约1亿行的表上。不相关,但为什么不直接执行
其中的d>'2019-09-20'::TIMESTAMP
,那么就不必费心进行所有这些日期转换了。@404在被截断的时间戳上建立索引也没有多大意义。而其中d>='2019-09-21'
就足够了,IMHO。
CREATE TABLE test
(
id bigserial PRIMARY KEY,
d timestamp without time zone NOT NULL
);
INSERT INTO test(d)
select gs FROM generate_series('2019-01-01'::timestamp,'2020-01-01'::timestamp,'4 hour':: interval) gs
;
CREATE INDEX f_date4
ON test
USING btree (d, id);
CREATE INDEX f_date5
ON test
USING btree (id, d);
VACUUM ANALYZE test;
EXPLAIN ANALYZE
SELECT id, d::date
FROM test
WHERE d >= '2019-09-21' -- NOTE: slightly changed condition
;
CREATE TABLE
INSERT 0 2191
CREATE INDEX
CREATE INDEX
VACUUM
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Index Only Scan using f_date4 on test (cost=0.28..17.32 rows=612 width=12) (actual time=0.025..0.160 rows=613 loops=1)
Index Cond: (d >= '2019-09-21 00:00:00'::timestamp without time zone)
Heap Fetches: 0
Planning Time: 0.285 ms
Execution Time: 0.218 ms
(5 rows)