2011-12-13 2 views
4

행 번호를 사용하여 저장 프로 시저에서 페이지 된 결과를 다시 얻습니다.주문을 사용할 때의 동적 주문

동적 케이스 문을 사용하여 순서를 지정하면 열 이름이 느려지는 것을 발견했습니다.하지만 모든 항목을 순서대로 하드 코딩하면 괜찮습니다.

문제 sp_executesql을

  ROW_NUMBER() OVER (ORDER BY 
      CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending = 0 THEN CLH.IdentityValue END DESC, 
      CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending = 1 THEN CLH.IdentityValue END 
      --CLH.CustomerName 

      ) AS [ROW] 

답변

1

을 전체 SQL 쿼리 하나의 문자열을 만들고 사용하지 않고에 의해 동적 순서를 빠르게 할 수있는 방법이 있나요은 SQL Server가 모든 매개 변수를 맞게 ONE 실행 계획을 구축을 위해 노력입니다 . 이것은 다른 매개 변수를 주면 마음이 바뀌지 않고 다른 색인을 선택한다는 것을 의미합니다. (different index 부분은 부적절한 색인 재 배열의로드가 매우 높을 수 있으므로 중요합니다.)

동적 플래닝을 생성하는 유일한 방법은 동적 SQL을 포함하는 새로운 실행 계획을 생성하는 것입니다. 피하고 싶다.


그러나; 동적 SQL과 SP_EXECUTESQL은 반드시 나쁜 생각은 아닙니다. 매개 변수화가 가능하므로 올바른 사용은 실행 계획 재사용을 허용하며 이러한 종류의 문제에서 매우 효율적일 수 있습니다.

동적 SQL을 피할 필요가있는 특별한 이유가 있습니까?


주변의 유일한 현실적인 작업은 쿼리가 다른 순서로 여러 번을 작성하고, T-SQL IF 블록으로 사용할 수있는 하나를 선택하는 것입니다. 이렇게하면 옵티 마이저가 다양한 실행 계획을 생성 할 수 있습니다. 당신의 잠재적 인 정렬 값의 일부 문자열이 아닌 경우

(ORDER BY 
     CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending = 0 
       THEN CLH.IdentityValue*-1 
      WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending = 1 
       THEN CLH.IdentityValue 
     END 
) 

물론,이 방법은 실용적이지 않을 것입니다 :이 같은 - 당신이 될 것 시도 할 수

0

것은 하나의 사건으로이 사건 개 조항을 결합 숫자의.

+1

영업 이익은 동적 경우 문을 열 이름을 사용하여 주문 일을 늦추고있다 "라고 -하지만 난 순서를 하드 코딩하면 모든 것이 괜찮 의해 ".인덱스 때문일 수 있습니다. 또한 순서대로 'case'를 사용하면 색인을 사용할 수 없습니다. – Andomar

1

단일 쿼리를 사용하면 SQL Server에서 매개 변수 값에 따라 다른 인덱스를 사용할 수 없습니다. AFAIK,이 두 가지 해결책이 있습니다 :

  • 빌드 저장 프로 시저에서 동적 쿼리 및 sp_executesql
  • 가 실제로

동적 쿼리 클라이언트 측에게 빌드 사용은, 그것은 PHP를 위해 열심히하고 코드 공유를위한 .NET 애플리케이션. 또는 다른 .NET 버전 일 수도 있습니다. 그러면 첫 번째 옵션이 더 강력한 선택이됩니다.

이렇게하는 가장 좋은 방법은 동적 SQL입니다. 그리고 그것은 꽤 놀랍습니다. : 당신은 종류에 따라 적게 처리를 그래서

0

여러 ROW_NUMBER 문을 시도

ROW_NUMBER() OVER (ORDER BY CLH.IdentityValue) DESC AS rnDesc, 
    ROW_NUMBER() OVER (ORDER BY CLH.IdentityValue) AS rnAscDesc, 
    ... 
ORDER BY 
    CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending = 0 THEN rnDesc END, 
    CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending = 1 THEN rnDesc END 
관련 문제