【发布时间】:2014-09-05 16:42:03
【问题描述】:
在 PostgreSQL 中,我的 tickets 表的日期字段上有一个索引。
当我将该字段与now() 进行比较时,查询非常有效:
# explain analyze select count(1) as count from tickets where updated_at > now();
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=90.64..90.66 rows=1 width=0) (actual time=33.238..33.238 rows=1 loops=1)
-> Index Scan using tickets_updated_at_idx on tickets (cost=0.01..90.27 rows=74 width=0) (actual time=0.016..29.318 rows=40250 loops=1)
Index Cond: (updated_at > now())
Total runtime: 33.271 ms
如果我尝试将其与 now() 减去一个间隔进行比较,它会走下坡路并使用位图堆扫描。
# explain analyze select count(1) as count from tickets where updated_at > (now() - '24 hours'::interval);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=180450.15..180450.17 rows=1 width=0) (actual time=543.898..543.898 rows=1 loops=1)
-> Bitmap Heap Scan on tickets (cost=21296.43..175963.31 rows=897368 width=0) (actual time=251.700..457.916 rows=924373 loops=1)
Recheck Cond: (updated_at > (now() - '24:00:00'::interval))
-> Bitmap Index Scan on tickets_updated_at_idx (cost=0.00..20847.74 rows=897368 width=0) (actual time=238.799..238.799 rows=924699 loops=1)
Index Cond: (updated_at > (now() - '24:00:00'::interval))
Total runtime: 543.952 ms
有没有更有效的使用日期算法进行查询的方法?
【问题讨论】:
-
版本?
select version()。发布表架构\d tickets -
你有
ANALYZE桌子吗?顺便说一句,第一个查询使用仅索引扫描,而第二个查询处理更多记录并且必须扫描表本身。 -
@IgorRomanchenko:我在第一个查询中看到了索引扫描,而不是仅索引扫描。
-
40250 行或 924699 行,有区别...
-
这不是添加本身。将
now()和now() - '24 hours'::interval替换为各自的时间戳文字,您会得到相同的结果。重要的是要找到的 预期 行数(74 对 897368)。正如我的回答中所解释的那样。
标签: sql postgresql indexing sql-execution-plan postgresql-performance