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索引应该也有用
我有一个 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索引应该也有用