Postgres慢限查询

时间:2014-02-21 19:46:37

标签: sql postgresql postgresql-9.2

我在pg

中有这个简单的查询
EXPLAIN ANALYZE 
select * from email_events 
where act_owner_id = 500
order by date desc
limit 500

第一次查询执行需要很长时间约7秒。

"Limit  (cost=0.43..8792.83 rows=500 width=2311) (actual time=3.064..7282.497 rows=500 loops=1)"
"  ->  Index Scan Backward using email_events_idx_date on email_events  (cost=0.43..233667.36 rows=13288 width=2311) (actual time=3.059..7282.094 rows=500 loops=1)"
"        Filter: (act_owner_id = 500)"
"        Rows Removed by Filter: 1053020"
"Total runtime: 7282.818 ms"

第一次执行后,我猜这个查询被缓存,并在20-30毫秒内完成。

为什么LIMIT在没有缓存时会如此慢?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

INDEX上的CLUSTER TABLE似乎解决了这个问题。似乎在批量数据加载后,数据遍布整个硬盘。 CLUSTER表将重新排序硬盘上的数据

答案 1 :(得分:1)

PostgreSQL认为向后扫描日期排序索引会更快(即以DESC顺序),读取每一行并丢弃没有正确act_owner_id的行。它必须执行1053020随机读取才能执行此操作,并且后向索引扫描也不是很快。

尝试在email_events(date DESC, act_owner_id)上创建索引。我认为 Pg将能够对其进行正向索引扫描,然后使用第二个索引术语来过滤行,因此它不应该进行堆查找。使用EXPLAIN进行测试并查看。