test테이블에 name,point 컬럼이 있습니다.
아래는 name별 point 기준으로 상위3개씩만 뽑아오는 쿼리와 실행계획입니다.
쿼리는 셀프조인형태로 서브쿼리의 값과 외부쿼리의 값을 비교하는데요
실행계획을 보시면 서브쿼리에서 먼저 인덱스 스켄을 한 후 외부 쿼리에서는 subplan의 결과값으로
Filter처리를 하고 있습니다.
제 예상은 외부나 내부 어느 한쪽의 테이블을 읽으면서 nested loop조인 형식으로 하나씩 값을 반대쪽이 쿼리에 공급하는 플랜이였습니다.
글을쓰다보니 제가 바보 같은 생각을 했네요..;;;
인라인뷰와 같이 집합을 만들어 놓지 않는 이상 nested loop로 풀리지 않는게 맞는거 같네요.
근데 어떻게 아래과 같은 실행계획이 나온지는 잘모르겠습니다.
어느쪽이 됐든 한쪽의 값을 다른쪽의 쿼리에 공급해줘야 할꺼 같은데 이 실행계획을 봐선 이해가 안되네요.
선배님들 조언부탁드립니다.
--------------------------------------------------------------
select t1.name, t1.point
from test t1
where t1.point >= (select min(t3.point)
from (select point
from test t2
where t2.name = t1.name
order by t2.point desc limit 3) t3)
order by name, point desc
--------------------------------------------------------------
Sort (cost=16577.61..16602.62 rows=10004 width=14)
Sort Key: name, point
-> Seq Scan on test t1 (cost=0.00..15912.93 rows=10004 width=14)
Filter: (point > (subplan))
SubPlan
-> Aggregate (cost=0.50..0.51 rows=1 width=4)
-> Limit (cost=0.00..0.45 rows=4 width=4)
-> Index Scan Backward using test_point on test t2 (cost=0.00..1123.75 rows=10004 width=4)
Filter: ((name)::text = ($0)::text)
|