저장 프로 시저에서 임시와 비교시 코드가 다른 계획을 만듭니다.


9

저장 프로 시저 내에서 실행할 때 잘못된 계획을 사용하지만 임시를 실행할 때 훨씬 더 나은 계획을 선택하는 delete 문이 있습니다.

쿼리에서 사용하는 테이블의 모든 인덱스를 다시 작성하고 모든 캐시를 삭제했습니다. 옵티마이 저는 여전히 저장 프로 시저에 대해 잘못된 계획을 선택합니다.

옵티마이 저가 저장 프로 시저와 임시 SQL에 대해 다른 실행 계획을 사용하는 이유를 알고 싶습니다.

업데이트 : 변수가 하드 코드 된 변수로 임시 코드를 실행했을 때 매개 변수 였을 것입니다. 올바른 값으로 "나쁜"계획을 얻을 수 있습니다 (날짜, 1 년 된 값) "좋은"계획을 생성하는 것 같습니다). 이제 쿼리 힌트를 사용하여 proc에 대한 "좋은"계획을 강요하려고합니다.

해결책 : OPTIMIZE FOR UNKNOWN 힌트를 사용하여 원하는 계획을 얻었습니다.


아마도 매개 변수 스니핑 일 것입니다 . 쿼리가 WHERE절 에서 변수를 참조합니까 ?
Nick Chammas

4
코드를 추가해주세요
gbn

또한 계획을 어딘가에 게시하십시오. 그대로, 왜 계획이 다른지 정확히 알려주는 것은 매우 어려울 것입니다.
Aaron Bertrand

더 많은 정보 : 계획과 코드를 조금 난독 처리하기 전까지는 게시 할 수 없습니다. 나는 몇 가지에 그들을 시도하려고합니다. 저장 프로 시저 계획 (bad)은 큰 테이블 (전체, 모든 파티션)의 클러스터 된 인덱스 스캔을 수행합니다. 그런 다음 루프를 사용하여 작은 테이블에서 행을 찾은 다음 작은 테이블에서 삭제합니다.
msgisme

Ad-hoc 코드 계획 (양호)은 작은 테이블 (5-10 개의 행만 있음)의 테이블 스캔을 수행하고 큰 테이블의 클러스터되지 않은 인덱스를 사용하여 PK에서 점검해야하는 행을 찾습니다. 큰 테이블의. 최대한 빨리 실제 계획을 세우려고 노력할 것입니다.
msgisme

답변:


5

일반적인 용의자 :

  1. 임시의 상수, 코드의 매개 변수
  2. 코드에서 데이터 유형의 불일치
  3. 매개 변수 스니핑

포인트 1 : 옵티마이 저는 상수에 가장 적합한 계획을 선택할 수 있습니다.
상수 변경 = 계획 변경 매개 변수화 된 plen이 재개 가능

포인트 2는 데이터 유형 우선 순위 때문에 암시 적 변환을 도입합니다 (
예 : nvarchar 매개 변수와 비교 한 varchar 열)

포인트 3 : 매개 변수 마스킹 또는 알 수없는 OPTIMIZE FOR
편집 사용 편집 : 테스트 : 저장 프로 시저를 실행하고 sp_updatestats를 실행 한 후 다시 실행하십시오. 캐시 된 계획을 무효화하여 계획 캐시를 지우는 것이 좋습니다.

편집 : jcolebrand의 의견 후

스니핑을 여러 가지 방법으로 비활성화 할 수 있습니다. 주요 3

  • 추천합니다. 이것은 바보 같은 IMO입니다.
  • 알 수없는 최적화 (sic)
  • 파라미터 마스킹

매개 변수 마스킹 :

DECLARE @MaskedParam varchar(10)
SELECT @MaskedParam = @SignaureParam

SELECT...WHERE column = @MaskedParam

마스킹과 OPTIMIZE 힌트는 동일한 효과를 갖습니다 (다른 이유로도 가능). 즉, 옵티마이 저는 통계 및 데이터 분포를 사용해야합니다 ( 참고 : Mark Storey-Smith에서 테스트중인 테스트 ) 는 자체 장점에 따라 매개 변수를 평가해야 합니까? , 그들이 마지막으로 부른 것이 아니라. 옵티마이 저는 다시 컴파일 할 수 있습니다. SQL Server 2005는 문 수준 재 컴파일을 추가하여 영향을 줄였습니다.

이제 "스니핑 된"매개 변수가있는 계획이 마스크 된 / "알 수없는"매개 변수와 비교하여 "고정적"인 이유는 확실하지 않습니다.

가장 간단한 코드를 제외하고 SQL Server 2000부터 매개 변수 마스킹을 사용했습니다. 더 복잡한 코드로 발생하기 쉽다고 언급했습니다. 그리고 내 이전 직장에서 계획 매개 변수 기본값을 변경할 수있는 몇 가지 보고서 프로세스가 있습니다. "화물 숭배"접근법은 지원 요청보다 쉽다고 생각합니다.

채팅 후 2011 년 10 월 2 일 2 일 수정

  • 알 수없는 한 매개 변수 마스킹 및 OPTIMIZE FOR UNKNOWN은
    힌트가 마스킹보다 깨끗하지만 SQL Server 2008에 추가되었습니다.

  • 컴파일시 매개 변수 스니핑이 발생합니다.
    WITH RECOMPILE은 실행될 때마다 새 계획을 생성합니다. 이는 기본 설정을 잘못 선택하면 계획에 영향을 미칩니다. 마지막 작업에서 일부 보고서 코드를 사용하여이를 쉽게 보여줄 수있었습니다. 매개 변수 기본값을 변경하면 제공된 매개 변수에 관계없이 계획이 변경되었습니다.

  • 이 MS Connect 기사는 흥미 롭습니다 : 저장 프로 시저 내에서 차선의 인덱스 사용 (아래 SO 답변 중 하나에서 언급)

  • Bob Beauchemin도 언급

뛰어난 문제

  • WITH RECOMPILE과 함께 스니핑이 계속 적용됩니까? 즉, 옵티마이 저가 계획을 폐기하는 것을 알고 있다면 재사용을 목표로 하는가?

  • 스니핑 된 계획이 "끈적 거리는"이유는 무엇입니까?

SO 링크 :


1. sp의 매개 변수는 코드 2의 변수입니다. 다시, 동일한 데이터 유형 3. 다양한 매개 변수를 모두 사용하여 매번 동일한 계획을 얻습니다. 매번 시도한 후 캐시를 지 웠습니다.
msgisme

1
Re : point 3. SQL Server에서 기존 계획을 무시하도록 명령을 실행 OPTION (RECOMPILE)하거나 전체 프로세스 WITH RECOMPILE를 실행할 수도 있습니다 .
Nick Chammas

3
BTW OPTIMIZE는 Microsoft이기 때문에 미국 회사입니다. :)
Nick Chammas

1
@Gbn 매개 변수 스니핑 방지 / 파괴에 대한 생각?
jcolebrand

1
@ jcolebrand : 간단한 대답은 "아니오"입니다 :-)
gbn

2

연결 계획에 대해 설정 한 ANSI 설정이 실행 계획 선택의 역할임을 잊지 마십시오. 앱이 저장 프로 시저를 호출 할 때 SSMS 연결과 다른 ANSI 설정이있을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.