Postgresql OR 语句减慢查询速度

Postgresql OR statement slowing down query

我有一个 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"

您的查询索引有误。 ("personOneId", "personTwoId") 上的多列 btree 索引不是很好,原因与在纸质 phone 书中查找所有名字为 'Samantha' 的人效率低下的原因相同,该书按以下方式排序先姓后名。

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