简体   繁体   中英

How to optimize query by index PostgreSQL

I want to fetch users that has 1 or more processed bets. I do this by using next sql:

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

But running EXPLAIN ANALYZE I noticed no index is used and query execution time is very high. I tried add partial index like:

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

But EXPLAIN ANALYZE output not changed:

 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)

Records with other statuses except (guessed, losed) a little.

How do I create proper index?

I'm using PostgreSQL 9.3.4.

I assume that the state mostly consists of 'guessed' and 'losed', with maybe a few other states as well in there. So most probably the optimizer do not see the need to use the index since it would still fetch most of the rows.

What you do need is an index on the user_id, so perhaps something like this would work:

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

Or, by not using a partial index:

CREATE INDEX idx_bets_state_user_id ON bets(state, user_id);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM