【问题标题】:Postgresql OR statement slowing down queryPostgresql OR 语句减慢查询速度
【发布时间】:2021-10-09 19:32:02
【问题描述】:

我有一个 PostgreSQL 查询,它在 where 子句中使用 OR 语句引用两列。

EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS) select * from "connection"
where "personOneId" = '?'
or "personTwoId" = '?'

我有一个关于“personOneId”的索引,而且查询速度很快。但是当我包含 OR "personTwoId" 时,查询会显着减慢。我最初尝试将“personOneId”和“personTwoId”都编入索引(多列索引),但它仍然执行“-> Parallel Seq Scan on connection”,并且查询的速度与使用索引时的速度相同。我的索引是错误的还是“OR”语句的预期行为?有没有办法改变这个查询以达到相同的结果,让 PG 正确使用索引?

执行计划

"Gather  (cost=1000.00..24641.09 rows=302 width=117) (actual time=47.352..144.044 rows=337 loops=1)"
"  Output: redacted"
"  Workers Planned: 2"
"  Workers Launched: 2"
"  Buffers: shared hit=1892 read=15205"
"  ->  Parallel Seq Scan on public.connection  (cost=0.00..23610.89 rows=126 width=117) (actual time=41.072..134.191 rows=112 loops=3)"
"        Output: redacted"
"        Filter: ((connection.""personOneId"" = 'redacted id'::uuid) OR (connection.""personTwoId"" = 'redacted id'::uuid))"
"        Rows Removed by Filter: 347295"
"        Buffers: shared hit=1892 read=15205"
"        Worker 0: actual time=39.153..134.249 rows=170 loops=1"
"          Buffers: shared hit=667 read=5645"
"        Worker 1: actual time=37.108..132.297 rows=134 loops=1"
"          Buffers: shared hit=651 read=4768"
"Planning Time: 0.217 ms"
"Execution Time: 147.659 ms"

【问题讨论】:

  • 还提供您的完整执行计划(EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS)

标签: sql postgresql query-optimization


【解决方案1】:

您为此查询设置了错误的索引。 ("personOneId", "personTwoId") 上的多列 btree 索引不是很好,原因与在纸质电话簿中查找所有名字为“Samantha”的人效率低下的原因相同,该电话簿先按姓氏排序,然后按名字排序。

如果您在每一列上都有单独的 btree 索引,那么它可以将它们与 BitmapOr 结合起来,这应该很快。或者,如果您切换到 GIN 索引,多列 GIN 索引也应该有用。

【讨论】:

  • 是的,你是对的,对每一列分别建立索引立即起作用,执行计划现在在两个索引上使用 BitmapOr。这将执行时间从平均 150 毫秒降低到平均 5 毫秒。谢谢。
猜你喜欢
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-10
  • 2023-03-22
  • 2011-10-04
  • 1970-01-01
  • 2015-11-27
相关资源
最近更新 更多