오늘은 지난 시간에 이어서 좀 더 깊이 있게 Parameter Sniffing이란 것을 소개해 드릴까 합니다.
오라클 DBMS에서는 Bind Peeking이라고도 불립니다.
우선, 파라미터 스니핑을 짧게 설명하자면 아래와 같습니다.
* Parameter Sniffing
- Parameter Sniffing은 SQL Server에서 프로시저를 처음 호출할 때(SQL Server 재 시작 등) 생성된 실행계획을
플랜 캐시에 저장한 뒤 이후 프로시저가 호출되면 실행계획을 세우지 않고 재사용 합니다.
그래서 성능을 고려해 프로시저를 이용하는 것이 큰 장점입니다.
하지만 이와 같은 문제가 오히려 성능에 치명적인 영향을 미치는 경우가 발생합니다.
데모를 통해서 함께 확인해 보시죠~
일단 샘플 데이터 만드는 게 귀차니즘이므로 AdventureWorks 예제 DB를 사용하겠습니다.
AdventureWorks DB에는 Sales.SalesOrderHeader(판매주문) 라는 테이블이 있습니다.
위 테이블 내 ShipDate(출고일자) 컬럼을 이용해 검색하는 프로시저를 하나 만들어 보죠~
참고로 ShipDate에는 2001-07-08 ~ 2004-08-07 까지의 데이터만 존재합니다.
--물건 출고일자 내 고객ID, 주문수량 검색 프로시저
CREATE PROCEDURE Usp_GetCustomerShipDates(
@ShipDateStart DATETIME ,
@ShipDateEnd DATETIME)
AS
SELECT CustomerID ,
SalesOrderNumber
FROM Sales.SalesOrderHeader
WHERE ShipDate BETWEEN @ShipDateStart AND @ShipDateEnd
GO
프로시저에서 검색할 때 유리하도록 인덱스도 만들어 주겠습니다.
--출고일자컬럼인덱스생성
CREATE NONCLUSTERED INDEX IDX_ShipDate_ASC
ON Sales.SalesOrderHeader (ShipDate)
GO
세팅은 끝났습니다~ Ho ya~
그럼 이제 프로시저를 호출 할건데요.
프로시저 호출 시 옵티마이저에서 실행계획을 두 가지를 비교해보기 위해서
한번은 출고일자를 처음부터 끝까지(풀스캔) 다른 하나는 하루치만 검색하도록 하겠습니다.(인덱스 검색)
통계를 확인하기 위해 옵션 ON! & 플랜캐시 삭제!
--쿼리실행 시간 및 통계설정
SET STATISTICS TIME ON;
SET STATISTICS IO ON;
--SQL Server 캐시삭제(모든 실행계획 삭제)
DBCC FREEPROCCACHE
그럼 풀스캔 하는 프로시저와 인덱스 검색하는 프로시저를 차례로 실행해 보겠습니다.
--데이터 선택도에 따라 옵티마이저 풀스캔 or 인덱스검색
EXEC user_GetCustomerShipDates '2001-07-08', '2004-08-07' -- 풀스캔(모든구간검색)
EXEC user_GetCustomerShipDates '2001-07-10', '2001-07-11' -- 인덱스검색
아래 실행 결과 입니다.(실행계획은 스압으로 인해 캡쳐하지 않았습니다 -_-+)
들어가면서 쓴 것과 같이 최초 호출되는 실행계획(풀스캔하는 실행계획)이 플랜캐시에 등록되었으므로,
인덱스 검색을 해야 하는 상황에서도 실행계획 재사용으로 인해 인덱스를 타지 않고 풀스캔 된 것을 확인 하실 수 있습니다.
이번엔 반대로 인덱스 검색을 실행하고 풀스캔을 실행해보도록 하겠습니다.
--SQL Server 캐시삭제(모든 실행계획 삭제)
DBCC FREEPROCCACHE
--이번엔 반대로 인덱스 검색 후 풀스캔
EXEC user_GetCustomerShipDates '2001-07-10', '2001-07-11' – 인덱스 검색
EXEC user_GetCustomerShipDates '2001-07-08', '2004-08-07' -- 풀스캔(모든구간검색)
아래 실행 결과 입니다.
위에서도 인덱스를 타야 되는 실행구문이 풀스캔 되는 문제도 성능에 영향을 미치겠지만 이번 결과가 더 충격적입니다.
동일한 검색이지만 풀스캔 시에는 논리적 읽기 수가 706 인 것에 비해
최초 실행 된 인덱스 검색 실행계획으로 Parameter Sniffing이 발생해서 논리적 읽기 수가 94468 약 133배 증가 했습니다.(랜덤 IO 발생)
성능적인 이슈만 봤을 때 Parameter Sniffing으로 인해 프로시저 사용이 언제나 향상된 성능을 보장하진 않습니다.
(프로시저 사용하지 말자는 뜻이 절~대 아닙니다!)
모니터링을 통해 평소에 정상적이던 프로시저가 갑자기 실행시간이나 IO 발생이 높아진다면
Parameter Sniffing을 의심해봐야 합니다.
Reference : Troubleshooting SQL Server A Guide for the Accidental DBA
'SQL Server > Tips' 카테고리의 다른 글
SQL Server ISNULL & COALESCE 비교 (0) | 2013.02.15 |
---|---|
SQL Server Parameter Solution (0) | 2013.02.15 |
SQL Server Missing Indexes (0) | 2012.12.13 |
SQL Server Backup all Databses (0) | 2012.12.13 |
SQL Server Startup time (0) | 2012.12.13 |