-- 적당히테이블생성
select
identity(int,1,1) as n
into nums
from sysindexes A, sysindexes B, sysindexes C
create clustered index idx_nums on nums (n)
MIN, MAX중 하나만 select 하는 경우
select min(n)
from nums with(nolock)
where n between 1 and 50
음.. Seek해서 알아서 1개를 잘 가져온 다음 Aggregate로 min 값을 가져왔다.
어쨌든 명령이 min 이기 때문에 Aggregate로 min을 가져오게 된다.
Min, Max 모두를 select 하는 경우
select min(n), max(n)
from nums with(nolock)
where n between 1 and 50
범위를 1~50까지 주었는데 이 범위 전체를 stream aggregate해서 min, max를 구했다.
음.. 좀더 똑똑했으면 좋겠는데.. 라는 생각이 든다.
Min, Max 모두를 select 하는데 범위를 좀더 크게 했을 때
select min(n), max(n)
from nums with(nolock)
where n between 1 and 50000
min과 max를 분리하여 각각 1개씩을 찾아와 stream aggregate 해서 min과 max를 찾아왔다.
요 위에서도 이런식으로 풀리기를 원했는데.. 흠흠..
이런 현상은 옵티마이저가 적당히 비용이 든다고 생각하면 그냥 실행해 버리는 이유 때문인 것 같다.
실행계획에 보면 모두 Seek후 Top 1을 하고 있는 것을 볼 수 있다.
그래서 Min, Max값 둘다 필요하다면 명시적으로 order by 해주고, Top 1 로 끊어주면 강제로 3번째와 같은 실행계획이 되게 할 수 있을것 같다.
Order by 를 해서 Top 1을 하는 경우
select top 1 n
from nums with(nolock)
where n between 1 and 50000
order by n desc
별반 차이는 없을것 같지만 가장 심플하게 원하는 값을 구해오게 된다.
하만철 / Ha Man-cheol