#title 최대값과 최소값의 처리 [[TableOfContents]] ==== 개요 ==== 가끔 다음과 같이 MAX() 와 MIN()의 처리를 하는 것을 볼 수 있다. {{{ SELECT TOP 1 UnitPrice FROM SalesOrderDetail ORDER BY UnitPrice Desc }}} 물론 UnitPrice에는 인덱스가 생성되지 않았다. Microsoft에서는 이런 식으로 MAX값을 구하는 것을 권장하지 않고, MAX()함수를 사용할 것을 권장한다. 만약 인덱스를 생성하는데 정렬 순서가 액세스에 영향을 미치지 않고, MAX()가 자주 사용된다면 DESC로 생성하면 MAX()대신 다음과 같은 방법을 사용할 수 있다. {{{ CREATE INDEX idx_UnitPrice ON SalesOrderDetail(UnitPrice DESC) GO SELECT TOP 1 UnitPrice FROM SalesOrderDetail WHERE UnitPrice > 0 GO --또는 SELECT TOP 1 UnitPrice FROM SalesOrderDetail (INDEX = idx_UnitPrice) GO SELECT MAX(UnitPrice) FROM SalesOrderDetail 'SalesOrderDetail' 테이블. 스캔 수 1, 논리적 읽기 수 2, 물리적 읽기 수 0, 미리 읽기 수 0. }}} ==== ORDERED FORWARD, ORDERED BACKWARD ==== 위의 쿼리들은 모두 같은 비용으로 처리되었다. TOP 1을 사용하여 인덱스의 정렬을 이용하여 MAX값을 가져온 것이다. 그러나 MSSQL Server는 이렇게 명시적으로 사용하지 않아도 인덱스가 있다면 TOP을 사용하여 MIN(), MAX()를 수행한다. 즉, 역순으로 인덱스를 읽거나, 아니면 그 반대 방향으로 인덱스를 읽는다. {{{ SELECT MAX(UnitPrice) FROM SalesOrderDetail }}} attachment:max.jpg {{{ SELECT MIN(UnitPrice) FROM SalesOrderDetail }}} attachment:min.jpg 표시하였듯이 FORWARD. BACKWARD라는 것을 볼 수 있을 것이다. 이것은 인덱스의 스캔방향을 나타내는 것이다. ==== Partitioned Table ==== SQL Server 2005버전 이상부터는 Partitioned Table에 대한 MIN(), MAX()에 대해서 사용상의 주의를 요한다. 옵티마이저의 실행계획에 영향을 주는 컬럼에 대한 변형을 주의해야 한다. 예를 들어 다음과 같은 경우다. {{{ --Partitioned Table에서는 이렇게 하면 성능 조낸 까임. 이런 븅신.. ㅡㅡ;; SELECT CONVERT(char(8), MAX(RegDT - 1), 112) DT FROM TableA --이렇게 해야 함 SELECT CONVERT(char(8), DT, 112) DT FROM (SELECT MAX(RegDT - 1) DT FROM TableA) A }}} attachment:partitioned_table_max.jpg