如何通过索引PostgreSQL优化查询

时间:2014-06-28 07:05:39

标签: sql postgresql indexing postgresql-9.3

我想获取有一个或多个已处理投注的用户。我通过使用下一个sql执行此操作:

SELECT user_id FROM bets 
WHERE bets.state in ('guessed', 'losed') 
GROUP BY user_id 
HAVING count(*) > 0;

但是运行EXPLAIN ANALYZE我注意到没有使用索引,查询执行时间非常长。我尝试添加部分索引,如:

CREATE INDEX processed_bets_index ON bets(state) WHERE state in ('guessed', 'losed');

但是EXPLAIN ANALYZE输出没有改变:

 HashAggregate  (cost=34116.36..34233.54 rows=9375 width=4) (actual time=235.195..237.623 rows=13310 loops=1)
   Filter: (count(*) > 0)
   ->  Seq Scan on bets  (cost=0.00..30980.44 rows=627184 width=4) (actual time=0.020..150.346 rows=626674 loops=1)
     Filter: ((state)::text = ANY ('{guessed,losed}'::text[]))
     Rows Removed by Filter: 20951
 Total runtime: 238.115 ms
 (6 rows)

记录除(猜测,失去)之外的其他状态。

如何创建正确的索引?

我正在使用PostgreSQL 9.3.4。

1 个答案:

答案 0 :(得分:3)

我认为国家主要是由猜测的'并且'失去',也许还有其他几个州。所以很可能优化器没有看到需要使用索引,因为它仍然会获取大部分行。

你需要的是user_id的索引,所以这样的东西可能会起作用:

CREATE INDEX idx_bets_user_id_in_guessed_losed ON bets(user_id) WHERE state in ('guessed', 'losed');

或者,不使用部分索引:

CREATE INDEX idx_bets_state_user_id ON bets(state, user_id);