OPTION FORCE ORDER는 행이 삭제 될 때까지 성능을 향상시킵니다.


9

필요에 따라 수행하지 않은 다소 복잡한 SQL Server 2008 쿼리 (약 200 줄의 상당히 밀도가 높은 SQL)가 있습니다. 시간이 지남에 따라 성능은 약 0.5 초에서 약 2 초로 떨어졌습니다.

실행 계획을 살펴보면 조인을 재정렬하여 성능을 향상시킬 수 있음이 분명했습니다. 나는 그것을했다. .. 약 .3 초까지. 이제 쿼리에 "OPTION FORCE ORDER"힌트 가 있으며 수명은 좋습니다.

오늘 함께 데이터베이스를 정리합니다. 행을 삭제하는 것을 제외하고 관련 데이터베이스에서 아무 조치도 취하지 않고 행의 약 20 %를 아카이브 합니다. 실행 계획이 TOTALLY hosed 됩니다. 특정 하위 트리가 반환 할 행 수를 완전히 잘못 판단하고 (예 : a)를 바꿉니다.

<Hash>

<NestedLoops Optimized='false' WithUnorderedPrefetch='true'>

이제 쿼리 시간이 약 .3 초에서 약 18 초로 급증합니다. (!) 행을 삭제했기 때문에. 쿼리 힌트를 제거하면 약 2 초 쿼리 시간으로 돌아갑니다. 더 좋지만 더 나쁩니다.

데이터베이스를 여러 위치와 서버로 복원 한 후 문제를 재현했습니다. 각 테이블에서 약 20 %의 행을 삭제하면 항상이 문제가 발생합니다.

  1. 강제 조인 순서가 쿼리 추정값을 완전히 부정확하게하여 쿼리 시간을 예측할 수없는 것이 정상입니까?
  2. 최적이 아닌 쿼리 성능을 수락하거나 매처럼보고 수동으로 쿼리 힌트를 편집해야한다고 기대해야합니까? 아니면 모든 조인도 암시합니까? .3 초에서 2 초로 큰 타격을받습니다.
  3. 행을 삭제 한 후 옵티마이 저가 폭발 한 이유는 분명합니까? 예를 들어, "예, 샘플 스캔이 필요했습니다. 데이터 히스토리의 초기에 대부분의 행을 아카이브했기 때문에 샘플에서 희소 한 결과를 얻었으므로 정렬 된 해시 작업의 필요성을 과소 평가했습니다"?

실행 계획을 보려면 게시 할 수있는 위치를 제안하십시오. 그렇지 않으면 가장 멋진 비트를 샘플링했습니다. 여기에 잘못된 추정의 기본이 있으며, parens의 숫자는 (추정 : 실제) 행입니다.

                             /  Clustered Index Scan (908:7229)
Nested Loops (Inner Join) --<
                             \  NonClustered Index Seek (1:7229)

내부 루프는 908 개의 행을 스캔하지만 52,258,441을 스캔합니다. 정확하다면이 분기는 12 초가 아닌 약 2ms 동안 실행되었을 것입니다. 행을 삭제하기 전에이 내부 조인 추정은 총계 2로만 해제되었으며 두 개의 클러스터 된 인덱스에서 해시 일치로 수행되었습니다.

답변:


6

강제 조인 순서가 쿼리 추정값을 완전히 부정확하게하여 쿼리 시간을 예측할 수없는 것이 정상입니까?

FORCE ORDER를 사용한다고해서 추정치가 부정확하지는 않습니다. 행이 삭제되었습니다. 테이블에서 통계를 강제로 업데이트하면 추정 정확도가 향상 될 수 있습니다.

최적이 아닌 쿼리 성능을 수락하거나 매처럼보고 수동으로 쿼리 힌트를 편집해야한다고 기대해야합니까? 아니면 모든 조인도 암시합니까? .3 초에서 2 초로 큰 타격을받습니다.

FORCE ORDER 힌트를 사용하지 않고 옵티 마이저에게 최상의 계획을 생성하는 데 필요한 정보를 제공하는 것이 바람직합니다. 그렇게함으로써, 그것은 해야 수동 개입없이 더 나은 기본 데이터 분포 변화에 대응. 즉, 데이터의 특성이 카디널리티가 시간별 또는 시간별로 크게 달라질 수있는 경우 계획 지침 을 사용하여 계획이 고정되었는지 확인하십시오.

행을 삭제 한 후 옵티마이 저가 폭발 한 이유는 분명합니까? 예를 들어, "예, 샘플 스캔이 필요했습니다. 데이터 히스토리의 초기에 대부분의 행을 아카이브했기 때문에 샘플에서 희소 한 결과를 얻었으므로 정렬 된 해시 작업의 필요성을 과소 평가했습니다"?

문제 테이블에서 행 수는 언급하지 않았지만 삭제는 다음 중 하나 일 수 있습니다.

  • 통계 업데이트를 트리거하기에 충분한 행을 제거하지 않았습니다. 행의 20 %가 수정되었지만 동적 임계 값 을 사용하기 위해 추적 플래그 2371 을 사용하는 옵션이있을 때 발생합니다 .
  • 통계 업데이트를 트리거했지만 수집 된 샘플은 대표적이지 않았습니다. WITH FULLSCAN 수동 업데이트를 실행하여이를 수정하십시오 .

또한 구식 매개 변수 스니핑 문제가 발생했을 수 있습니다.이 옵션에는 수많은 옵션이 있습니다. WITH RECOMPILE 은이 큰 쿼리로 지정하는 비싼 옵션 일 수 있지만 프로 시저 및 명령문 레벨 모두에서 조사 할 가치가 있습니다.


간단히 설명하자면 아마도 의미론 일 것입니다. "강제 주문을 사용한다고해서 추정치가 부정확하지는 않습니다. 행을 삭제 한 것입니다." 따라서 "FORCE ORDER"를 제거하면 쿼리가 크게 개선 될 가능성이 무작위라고 생각하십니까? 힌트는 최적화 프로그램이 통계에 의존하지 않았으며, 덜 신뢰할만한 통계는 거의 중추적이지 않기 때문에 응용 프로그램 테스트에서 발견되지 않았습니까?
shannon

저는 그렇습니다. 옵티마이 저가 선호하는 계획 선택은 부정확 한 통계에 대처하기 위해 발생하지만 조인 명령을 강제로 발생시킨 계획은 그렇지 않습니다. 나는 강제 평가가 통계 평가에 어떤 변화를 일으켰는지 모르고있다. 또한 최적화를 위해 선택한 값이 적절한 지 고려해야합니다. 통계는 절대적으로 괜찮을 수도 있지만 대표가 아닌 가치를 기반으로 계획을 강요하고 있습니다.
Mark Storey-Smith

권리. 매개 변수를 최적화 한 그대로 전달하는 것과 동일한 성능 문제가 있습니다. 다시 감사합니다.
shannon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.