2012-05-30 2 views
1

WHERE 절에서 이와 같은 조건을 사용할 때 Table.Column = @Param 또는 @Param IS NULL Column에 INDEX를 사용하지 않습니다.쿼리 최적화; Table.Column = @Param 또는 @Param IS NULL

인가 그것은 사실이고 또한 INDEX

쿼리 예

SELECT Col1, Col2 ... 
FROM Table 
WHERE (Col1 = @col OR @col IS NULL) 
AND (Col2 = @col2 OR @col2 IS NULL) 
AND (Col3 = @col3 OR @col3 IS NULL) 

어떤 도움을 사용하는 쿼리의이 종류를 작성하는 방법 그럼합니다.

+0

내 질문의 서식을 지정하지 않으셔서 죄송합니다. 편집자가 옵션 및 미리보기를 제공하지 않습니다. 왜 그런지 모르겠습니다. – Kashif

+0

성능은 향상되지 않지만이 조건은 좀 더 우아한 방법으로 작성 될 수 있습니다. col1 = isnull (@col, col1) – heximal

+1

다음은 동적 검색 조건에 대한 아주 완벽한 참조입니다. http : // www. sommarskog.se/dyn-search.html SSMS에서 실행 계획을 검토하여 쿼리가 인덱스를 사용하는지 쉽게 확인할 수 있습니다. – Pondlife

답변

5

불행히도 실행 계획 생성은 예상대로 작동하지 않습니다.

단일 쿼리의 경우 단일 플랜이 만들어집니다. 해당 계획을 작성할 때 사용할 색인이 선택되어 고정됩니다. 당신이 제공하는 매개 변수, 동일한 계획, 동일한 색인 등이 항상 사용되는 것은 중요하지 않습니다.

otpimiser는 모든 이벤트 발생에 적합한 최상의 계획을 찾기 위해 시도한을 가지고 있지만이 유형의 쿼리의 성격 상 하나가 없습니다. 당신이 전혀 색인을 사용하지 않은 계획에 의해 생성 된 특징.


용액 동적 SQL을 사용하는 것이다. 이것은 어색해 보입니다. 그러나 sp_executesql과 함께 매개 변수화 된 쿼리를 사용하는 경우 실제로는 매우 복잡하고 매우 효과적 일 수 있습니다. 여기

주제에 매우 유용한 기사에 대한 링크입니다 : dynamic search

그것은 아주 깊이, 그러나 그것은 이 문제에 대한 매우 강력한 방법입니다.

+0

이것은 좋은 ORM 도구가 수행하는 것입니다. 우수 답변. –

-1

왜 시도하지 않는 : 귀하의 질문에 대해

SELECT Col1, Col2 ... 
FROM Table 
WHERE Col1 = IsNull(@col,Col1) 
AND Col2 = IsNull(@col2,Col2) 
AND Col3 = IsNull(@col3,Col3) 

을 : 조회 분석기는 column1,2,3에 인덱스를 사용하지 않는 말? 3 열 모두에 대해 색인을 만들었습니까? 그런 다음 다른 것과 상관없이 사용하십시오. OR IS NULL

+0

실행 계획을 생성하는 측면에서 보면, 이것은 OP가 이미 경험하고있는 것과 똑같은 행동을합니다. 즉, 불행히도 도움이되지 않습니다. – MatBailie

+0

나는 당신이 권리인지 의심의 여지가 없지만 어쨌든 실행 계획이 그의 인덱스를 사용하지 않는 이유를 이해하지 못한다. – YvesR

+0

내 대답에는이 부분을 설명하는 기사 링크가 있습니다. 내 대답은 표면을 간지럽 히지만 기사를 작성하는 것이 전체적이고 완전한 대답을 제공하는 것입니다. 불행히도 최고의 링크를 읽으십시오. – MatBailie

-1

시도 모두에 인덱스가 WHERE 절 열 아래에 주어진 더 구조화 된 쿼리를 사용하려고합니다 : -

SELECT COL1, Col2의 ... 표 enter code here FROM WHERE COL1 = COALESCE (@ COL, COL1) enter code here Col2의 AND = COALESCE (@ COL2, Col2의) enter code here AND 열 3 = COALESCE (@ COL3, 열 3) enter code here

,

COALESCE() 함수는 첫 번째 널 (null)이 아닌 인수를 리턴하므로 STATUS가 NULL이면 "를 리턴합니다.아주 심하게 수행해야처럼

+0

이것은 내 답변에 언급 된 이유에 대해 어떠한 차이도 만들지 않으며 링크 된 기사에서 참조합니다. * (그리고 그 질문에 대한 언급에 링크되어 있습니다.) * – MatBailie

+0

또 다른 방법이 있습니다. 그러나 나는 당신의 면제 환경에 어떤 특색이 있을지 생각하지 않습니다. 주 테이블에서 기본 키에 대한 인덱스를 만듭니다. 그런 다음 최종 쿼리에서 기본 키에 대한 검색을 제공하고 레코드를 임시로 두십시오. 표. 이제 임시 테이블의 모든 열에 대한 인덱스를 만듭니다. 마지막으로 임시 테이블에서 선택한 쿼리를 작성하십시오. –

0
SELECT Col1, Col2 ... 
FROM Table 
WHERE EXISTS(
    SELECT Col1, Col2, Col3 
    INTERSECT 
    SELECT @col, @col2, @col3) 

직관적으로,이 보이지만, SQL 서버의 쿼리 최적화는 INTERSECT 특별 대우를 제공하는 방법을 알고, 내부적으로 (의사-SQL)를 같은

SELECT Col1, Col2 ... 
FROM Table 
WHERE (Col1, Col2, Col3) IS (@col, @col2, @col3) 

로 변환 쿼리 계획에서 볼 수 있습니다. 이 열에 색인이 있으면 사용할 수 있고 사용할 수 있습니다.

원래이 게시물은 Paul White의 Undocumented Query Plans: Equality Comparisons 블로그 게시물에서 가져온 것으로 재미있는 내용 일 수 있습니다.