[여러분의 이름은 여기에 있습니다]!
아뇨, 유감입니다! 약간의 기초부터 시작하여 순식간에 고착시킬 수 있습니다.
당신이 겪고있는 것을 Parameter Sniffing이라고합니다.
이상한 이상한 문제를 해결하는 방법입니다. 이름이 혀에서 바로 굴러갑니다. 다람쥐에 대한 독일어 단어처럼.
그리고 그것은 보통 당신의 친구입니다.
쿼리가 서버에 도달하면 계획을 컴파일해야합니다. 나중에 시간과 자원을 절약하기 위해 실행 계획은 매개 변수가 코드를 처리하고 리턴하게하는 예상 행을 기반으로 캐시됩니다.
이 나쁜 상황을 파악하는 가장 쉬운 방법은 두 편향 인구의 항목을 계산해야하는 저장 프로 시저를 상상하는 것입니다.
예를 들면 다음과 같습니다.
분명히 그 코드를 한 번 실행하면 다른 코드보다 훨씬 더 많은 작업을 수행해야하며 완전히 다른 양의 작업을 수행하려는 쿼리 계획은 완전히 다르게 보일 것입니다.
나는 무엇에 반대하고 있는가?
찾기, 테스트 및 수정하기가 실제로 어려운 문제입니다.
- 일관되게 발생하지 않기 때문에 찾기가 어렵습니다.
- 어떤 계획이 다른 계획을 일으키는 지 알아야하기 때문에 테스트하기가 어렵습니다
- 때로는 쿼리 및 인덱스 조정이 필요하기 때문에 수정하기가 어렵습니다.
- 쿼리 나 인덱스를 변경하지 못할 수 있으므로 수정하기가 어렵습니다.
- 쿼리 나 인덱스를 변경하더라도 여전히 되돌아 올 수 있으므로 수정하기가 어렵습니다.
빠른 수정
때때로, 당신이 필요로하는 것은 약간 명확합니다. 또는 계획 캐시가 수행합니다.
저장 프로 시저 인 경우
실행 해보십시오 EXEC sys.sp_recompile @objname = N'schema.procname'
. 그러면 다음에 실행될 때 프로 시저가 새 계획을 다시 컴파일하게됩니다.
이것이 해결되지 않는 것 :
이것이 보증하지 않는 것 :
- 재 컴파일 후에 실행되는 다음 프로세스는 좋은 계획을 제공하는 매개 변수를 사용합니다.
sp_recompile
테이블이나 뷰를 가리킬 수도 있지만 해당 테이블이나 뷰에 닿는 모든 코드가 다시 컴파일됩니다. 이로 인해 문제가 훨씬 더 어려워 질 수 있습니다.
매개 변수화 된 쿼리 인 경우
직업이 좀 더 어려워요. SQL 핸들을 추적해야합니다. sp_recompile
테이블 또는 뷰에 대해 사용 하는 것과 마찬가지로 전체 계획 캐시를 해제하지 않으려 는 경우 의도하지 않은 결과를 유발할 수 있습니다.
명령을 알아내는 가장 쉬운 방법은 sp_BlitzWho *! 캐시에서 단일 계획을 제거하는 명령이있는 "fix parameter sniffing"이라는 열이 있습니다. 그러나 이것은 재 컴파일과 동일한 단점이 있습니다.
이것이 해결되지 않는 것 :
이것이 보증하지 않는 것 :
- 재 컴파일 후에 실행되는 다음 프로세스는 좋은 계획을 제공하는 매개 변수를 사용합니다.
여전히 도움이 필요합니다!
다음과 같은 것들이 필요합니다 :
- 가능한 경우 좋은 쿼리 계획
- 잘못된 쿼리 계획
- 사용 된 매개 변수
- 문제의 쿼리
- 테이블 및 인덱스 정의
쿼리 계획 및 쿼리 받기
쿼리가 실행중인 경우 sp_BlitzWho * 또는 sp_WhoIsActive 를 사용하여 현재 실행중인 쿼리를 캡처 할 수 있습니다 .
EXEC sp_BlitzWho;
EXEC sp_WhoIsActive @get_plans = 1;
쿼리가 현재 실행되고 있지 않으면 sp_BlitzCache *를 사용하여 계획 캐시에서 쿼리를 확인할 수 있습니다 .
SQL Server 2016 이상을 사용 중이고 쿼리 저장소를 설정 한 경우 sp_BlitzQueryStore *를 사용할 수 있습니다 .
EXEC dbo.sp_BlitzCache @StoredProcName = 'Your Mom';
EXEC dbo.sp_BlitzQueryStore @StoredProcName = 'Your Mom';
이를 통해 저장 프로 시저의 캐시 된 버전을 추적 할 수 있습니다. 매개 변수가있는 코드 인 경우 검색이 조금 더 어렵습니다. 그래도 도움이 될 수 있습니다.
EXEC dbo.sp_BlitzCache @QueryFilter = 'statement';
그중 어느 것과 비슷한 결과가 나타납니다. 다시, 멋진 청색 클릭 컬럼을 초대하는 쿼리 계획은 당신의 친구입니다.
계획을 공유하는 가장 쉬운 방법은 Paste The Plan *을 사용하거나 XML을 pastebin에 덤프하는 것입니다. 그것을 얻으려면 파란 clicky 열 중 하나를 클릭하십시오. 쿼리 계획이 새 SSMS 탭에 나타납니다.
회사의 코드와 쿼리를 공유하는 데 익숙하다면 Sentry One의 무료 Plan Explorer 도구 를 사용하여 계획을 익명화 할 수 있습니다. 이로 인해 도움이 더 어려워집니다. 익명화 된 코드는 읽고 이해하기가 훨씬 어렵습니다.
우리가 이야기 한이 모든 도구는 쿼리 텍스트를 반환해야합니다. 여기서 다른 작업을 수행 할 필요가 없습니다.
매개 변수를 얻는 것이 조금 더 어렵습니다. Plan Explorer를 사용 하는 경우 하단에 탭이 있습니다.
sp_BlitzCache *를 사용하는 경우 저장 프로 시저에 대한 실행 문을 제공하는 클릭 가능한 열이 있습니다.
테이블 및 인덱스 정의 얻기
SSMS를 마우스 오른쪽 버튼으로 쉽게 클릭하여 스크립트를 작성할 수 있습니다.
한 번에 모든 것을 얻으려면 sp_BlitzIndex *가 테이블을 직접 가리키면 도움이 될 수 있습니다.
EXEC dbo.sp_BlitzIndex @DatabaseName = 'StackOverflow2010',
@SchemaName = 'dbo',
@TableName = 'Users';
이렇게하면 테이블 정의 (create 문은 아니지만)와 모든 인덱스에 대한 create 문이 제공됩니다.
이 정보를 수집하여 질문에 추가하면 사람들에게 충분한 정보가 도움이되거나 올바른 방향으로 안내됩니다.
나는 그것을하고 싶다!
글쎄요 나는 당신을 위해 행복 해요. 당신은 미친 사람입니다.
사람들이 매개 변수 스니핑을 "수정"한다고 생각하는 많은 방법이 있습니다.
그러나 이들은 실제로 다른 방법으로 매개 변수 스니핑을 비활성화합니다. 그것은 그들이 문제를 해결할 수 없다고 말하는 것이 아니라, 근본 원인에 실제로 도달하지는 않습니다.
근본 원인을 찾는 것이 일반적으로 어렵 기 때문입니다. 성가신 "계획 품질 문제"를 찾아야합니다.
빠른 대 느린 계획으로 시작하여 다음과 같은 차이점을 찾으십시오.
또한 매개 변수 스니핑에 코드를 민감하게 만드는 다른 연산자를 찾으십시오.
- 조회
- 정렬
- 조인 유형
- 메모리 부여 (및 확장으로 유출)
- 스풀
탐색 대 스캔, 인덱스 조각화 또는 사람들이 옷을 입히고 짐작할 수있는화물에 너무 얽매이지 마십시오.
일반적으로 매우 기본적인 인덱싱 문제가 있습니다. 때로는 코드를 약간 다시 작성해야합니다.
매개 변수 스니핑에 대한 자세한 내용을 보려면
이 글을 읽고 있는데 링크 나 유용한 도구를 놓쳤다 고 생각되면 의견을 남겨주십시오. 이 최신 정보를 유지하기 위해 최선을 다하겠습니다.