(질문이 SO에서 옮겨졌습니다.)
클러스터 된 인덱스가있는 테이블 (더미 데이터)에 2 개의 열이 있습니다.
이제 두 가지 쿼리를 실행합니다.
declare
@productid int =1 ,
@priceid int = 1
SELECT productid,
t.priceID
FROM Transactions AS t
WHERE (productID = @productid OR @productid IS NULL)
AND (priceid = @priceid OR @priceid IS NULL)
SELECT productid,
t.priceID
FROM Transactions AS t
WHERE (productID = @productid)
AND (priceid = @priceid)
두 쿼리의 실제 실행 계획은 다음과 같습니다.
보다시피, 첫 번째는 SCAN을 사용하고 두 번째는 SEEK를 사용하고 있습니다.
그러나 OPTION (RECOMPILE)
첫 번째 쿼리에 추가 하여 실행 계획에서도 SEEK를 사용했습니다.
DBA 채팅 친구들은 다음과 같이 말했습니다.
쿼리에서 @ productid = 1은 (productID = @ productID 또는 @productID IS NULL)을 (productID = @ productID)로 단순화 할 수 있음을 의미합니다. 전자는 @productID의 값으로 작동하려면 스캔이 필요하고 후자는 검색을 사용할 수 있습니다. 따라서 RECOMPILE을 사용할 때 SQL Server는 실제로 @productID에 어떤 값이 있는지 확인하고 최상의 계획을 세웁니다. @productID에 null이 아닌 값을 사용하면 검색이 가장 좋습니다. @productID의 값을 알 수없는 경우 계획은 @productID의 가능한 모든 값에 맞아야하며 스캔이 필요합니다. 경고 : OPTION (RECOMPILE)은 계획을 실행할 때마다 계획을 다시 컴파일하여 실행마다 몇 밀리 초를 추가합니다. 쿼리가 매우 자주 실행되는 경우에만 문제가됩니다.
또한 :
@productID가 null이면 어떤 값을 찾고 싶습니까? 답 : 추구 할 것이 없습니다. 모든 가치가 있습니다.
나는 이해 OPTION (RECOMPILE)
세력 SQL 서버는이 값 매개 변수 실제 무엇을보고, 그것으로 추구 할 수 있는지.
그러나 이제는 사전 컴파일의 이점을 잃습니다.
질문
IMHO-SCAN은 param이 null 인 경우에만 발생합니다.
괜찮습니다-SQL SERVER가 SCAN에 대한 실행 계획을 작성하게하십시오.
그러나 SQL Server 에서이 쿼리를 여러 번 실행하여 값을 여러 번 1,1
실행하면 다른 실행 계획을 작성하고 SEEK를 사용하지 않는 이유는 무엇입니까?
AFAIK-SQL은 가장 인기있는 쿼리에 대한 실행 계획을 만듭니다 .
SQL Server가 다음에 대한 실행 계획을 저장하지 않는 이유는 무엇입니까?
@productid int =1 , @priceid int = 1
(나는 그 값으로 여러 번 실행합니다)
- 향후 호출을 위해 SQL이 해당 실행 계획 (SEEK를 사용함)을 유지하도록 할 수 있습니까?