2016-08-31 5 views
0

인덱스가있는 테이블이 있습니다 (A 열, B 열). 그리고 다음과 같은 쿼리를 실행하고 있습니다.IN을 사용한 postgres 쿼리가 매우 느림

SELECT * FROM table WHERE (A, B) IN ((a_1, b_1), (a_2, b_2), ..., (a_5000, b_5000)) 

이 쿼리는 매우 느립니다. 대신에 하나 개의 인덱스가 5000 개 값으로 스캔하고의

Bitmap Heap Scan on table 
    Recheck Cond: (((A = a_1) AND (B = b_1)) OR ((A = a_2) AND (B = b_2)) OR ... 
    -> BitmapOr 
     -> Bitmap Index Scan on idx 
       Index Cond: ((A = a_1) AND (B = b_1)) 
     -> Bitmap Index Scan on idx 
       Index Cond: ((A = a_2) AND (B = b_2)) 
     ...(5000 other Bitmax Index Scan) 

, 포스트 그레스 쿼리가 너무 느린 이유를 설명하는 시간에 하나 개의 값을 5000 인덱스 스캔을하고있는 것 같다 : 계획은 것 같습니다.

SELECT * FROM table WHERE A IN (a_1, ..., a_5000) 

결과를 페치하고 앱 (파이썬) 내부의 열을 필터링 B :

실제로는가 someting 같이 수행 방법 빠르다.

저는 결과가 합리적인 실행 시간을 가진 postgres로 이미 필터링되도록하는 것이 좋습니다. 해결 방법이 있습니까? CTE를에 가입

답변

1

시도 :

with value_list (a,b) as (
    values 
     (a_1, b_1), 
     (a_2, b_2), ..., 
     (a_5000, b_5000) 
) 
select * 
from table t 
    join value_list v on (t.a, t.b) = (v.a, v.b); 

가 (이 값 목록에는 중복이없는 가정)

+0

흥미 롭다. 왜 어떤 변화가 있어야합니까? – zerkms

+0

@zerkms : 이론 (희망)은 옵티마이 저가 각 값에 대해 하나의 스캔 대신 모든 값에 대해 단일 인덱스 스캔을 수행하도록 속일 것입니다. –

+0

그것은 작동합니다! 플래너는 실제로 하나의 hashjoin을 사용합니다. 플래너가 첫 번째 쿼리를 처리 할 정도로 똑똑하지는 않지만 이상하다는 것을 알았습니다. –