내 (간체) 쿼리 :
SELECT a.id FROM a LEFT JOIN b ON b.id = a.id WHERE b.id IS NULL ORDER BY id;
이 같은 쿼리 계획은 작동합니다 플래너가 거라고 생각하면
는
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Merge Anti Join (cost=0.57..3831.88 rows=128092 width=8)
Merge Cond: (a.id = b.id)
-> Index Only Scan using a_pkey on a (cost=0.42..3399.70 rows=130352 width=8)
-> Index Only Scan using b_pkey on b (cost=0.15..78.06 rows=2260 width=8)
(4 rows)
그러나, 때때로 PostgreSQL의 9.5.9 순차 스캔으로 전환 할 것 더 나아야합니다 (Why does PostgreSQL perform sequential scan on indexed column? 참조). 그러나 제 경우에는 상황이 악화되었습니다.
set enable_seqscan to off;
PostgreSQL의 문서는이 ALTER TABLESPACE를 사용하여 seq_page_cost이다 할 수있는 적절한 방법을 말한다
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Merge Anti Join (cost=405448.22..39405858.08 rows=1365191502 width=8)
Merge Cond: (a.id = b.id)
-> Index Only Scan using a_pkey on a (cost=0.58..35528317.86 rows=1368180352 width=8)
-> Materialize (cost=405447.64..420391.89 rows=2988850 width=8)
-> Sort (cost=405447.64..412919.76 rows=2988850 width=8)
Sort Key: b.id
-> Seq Scan on b (cost=0.00..43113.50 rows=2988850 width=8)
(7 rows)
내 (해킹) 솔루션은 순차 스캔을 억제하는 것이 었습니다. 인덱스 된 열에서 ORDER BY를 사용하는 경우이 방법을 사용하는 것이 좋지만 잘 모르겠습니다. https://www.postgresql.org/docs/9.1/static/runtime-config-query.html
우리가 분석하고 더 잘 대답 할 수 있도록 지금 가지고있는 쿼리 (및 계획)를 게시하십시오. BHS가 더 효율적이기 때문에 BHS를 사용할 수도 있지만 왼쪽 결합의 결과 일 수도 있으므로 피할 수 있습니다. 'NOT EXISTS','SELECT ... EXCEPT' 등과 같은 다른 종류의 질의에 대해'EXPLAIN ANALYZE'를 할 수 있습니다. – jmz
여전히 이론적입니다. 포스트 그레스 (Postgres)는 인덱스 안티 조인 (anti-join)이 어떤 정보를 놓치지 않는다는 것을 확신 할 수 없기 때문에 가능하지 않다고 생각한다. 그래서 테이블을 일찍 점검해야합니다. –
이론적인데 왜 PostgreSQL이 인덱스 스캔을 할 수 없다고 생각합니까? Richard Huxton은 이미 색인 스캔을 사용하는 예를 보여주었습니다. –