我想获取有一个或多个已处理投注的用户。我通过使用下一个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。
答案 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);