【问题标题】:How to optimize query by index PostgreSQL如何通过索引 PostgreSQL 优化查询
【发布时间】:2014-08-19 07:29:03
【问题描述】:

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

【问题讨论】:

  • 请在每个帖子中坚持一个问题 - 如果您想讨论两个不同的问题,请发布一个新问题。如果你愿意,可以在它们之间建立链接。
  • “除了(猜到,输了)一点点之外的其他状态的记录。”。嗯?我不明白这是什么意思。无论如何:第一个想法,你ANALYZE bets;guessedlosed(顺便说一下“丢失”)状态下的行所占的比例是多少?
  • 抱歉我的英语不好)投注有三种状态,包括:猜中、输了、进行中。比例约为45/45/10。

标签: sql postgresql indexing postgresql-9.3


【解决方案1】:

我假设状态主要由“猜测”和“失败”组成,其中可能还有一些其他状态。所以很可能优化器看不到使用索引的必要性,因为它仍然会获取大部分行。

您需要的是 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);

【讨论】:

  • 不使用部分索引给了我预期的结果!谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2014-06-13
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多