어제보다 내 쿼리가 왜 갑자기 느려 집니까?


76

[염소]

(하나 확인)

[ ] Well trained professional, [ ] Casual reader, [ ] Hapless wanderer,

나는 (해당 사항을 모두 체크하십시오)

[ ] query [ ] stored procedure [ ] database thing maybe  

제대로 작동 했음 (해당되는 경우)

[ ] yesterday [ ] in recent memory [ ] at some point 

그러나 지금 갑자기 느려집니다.

이미 차단되지 않았는지, 장기 유지 관리 작업, 보고서 또는 기타 대역 외 프로세스의 희생자가 아닌지 확인했습니다.

문제는 무엇이며 어떻게해야합니까? 도움을 얻기 위해 어떤 정보를 제공 할 수 있습니까?

[*Insert appropriate closing remarks*]

답변:


88

[여러분의 이름은 여기에 있습니다]!

아뇨, 유감입니다! 약간의 기초부터 시작하여 순식간에 고착시킬 수 있습니다.

당신이 겪고있는 것을 Parameter Sniffing이라고합니다.

이상한 이상한 문제를 해결하는 방법입니다. 이름이 혀에서 바로 굴러갑니다. 다람쥐에 대한 독일어 단어처럼.

그리고 그것은 보통 당신의 친구입니다.

쿼리가 서버에 도달하면 계획을 컴파일해야합니다. 나중에 시간과 자원을 절약하기 위해 실행 계획은 매개 변수가 코드를 처리하고 리턴하게하는 예상 행을 기반으로 캐시됩니다.

이 나쁜 상황을 파악하는 가장 쉬운 방법은 두 편향 인구의 항목을 계산해야하는 저장 프로 시저를 상상하는 것입니다.

예를 들면 다음과 같습니다.

  • 다 치지 않은 CrossFit 셔츠를 입은 사람들 : Zero

  • 이길 때이기는 CrossFit 셔츠를 입은 사람들 : 모두

분명히 그 코드를 한 번 실행하면 다른 코드보다 훨씬 더 많은 작업을 수행해야하며 완전히 다른 양의 작업을 수행하려는 쿼리 계획은 완전히 다르게 보일 것입니다.

나는 무엇에 반대하고 있는가?

찾기, 테스트 및 수정하기가 실제로 어려운 문제입니다.

  • 일관되게 발생하지 않기 때문에 찾기가 어렵습니다.
  • 어떤 계획이 다른 계획을 일으키는 지 알아야하기 때문에 테스트하기가 어렵습니다
  • 때로는 쿼리 및 인덱스 조정이 필요하기 때문에 수정하기가 어렵습니다.
  • 쿼리 나 인덱스를 변경하지 못할 수 있으므로 수정하기가 어렵습니다.
  • 쿼리 나 인덱스를 변경하더라도 여전히 되돌아 올 수 있으므로 수정하기가 어렵습니다.

빠른 수정

때때로, 당신이 필요로하는 것은 약간 명확합니다. 또는 계획 캐시가 수행합니다.

저장 프로 시저 인 경우

실행 해보십시오 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 문이 제공됩니다.

이 정보를 수집하여 질문에 추가하면 사람들에게 충분한 정보가 도움이되거나 올바른 방향으로 안내됩니다.

나는 그것을하고 싶다!

글쎄요 나는 당신을 위해 행복 해요. 당신은 미친 사람입니다.

사람들이 매개 변수 스니핑을 "수정"한다고 생각하는 많은 방법이 있습니다.

그러나 이들은 실제로 다른 방법으로 매개 변수 스니핑을 비활성화합니다. 그것은 그들이 문제를 해결할 수 없다고 말하는 것이 아니라, 근본 원인에 실제로 도달하지는 않습니다.

근본 원인을 찾는 것이 일반적으로 어렵 기 때문입니다. 성가신 "계획 품질 문제"를 찾아야합니다.

빠른 대 느린 계획으로 시작하여 다음과 같은 차이점을 찾으십시오.

  • 사용 된 인덱스
  • 주문 가입
  • 직렬 대 병렬

또한 매개 변수 스니핑에 코드를 민감하게 만드는 다른 연산자를 찾으십시오.

  • 조회
  • 정렬
  • 조인 유형
  • 메모리 부여 (및 확장으로 유출)
  • 스풀

탐색 대 스캔, 인덱스 조각화 또는 사람들이 옷을 입히고 짐작할 수있는화물에 너무 얽매이지 마십시오.

일반적으로 매우 기본적인 인덱싱 문제가 있습니다. 때로는 코드를 약간 다시 작성해야합니다.

매개 변수 스니핑에 대한 자세한 내용을 보려면

이 글을 읽고 있는데 링크 나 유용한 도구를 놓쳤다 고 생각되면 의견을 남겨주십시오. 이 최신 정보를 유지하기 위해 최선을 다하겠습니다.



28

매개 변수 스니핑은 쿼리의 다양한 성능에 유일한 원인이 아닙니다. 다음과 같은 일반적인 이유 중 하나가 동일한 증상을 보일 수 있습니다.

  1. 데이터 분배 / 볼륨이 변경되어 옵티 마이저 검색 트리 의사 결정 팁 포인트를 넘어
  2. 색인 / 파일이 조각화되었습니다.
  3. 통계가 업데이트 / 추가 / 삭제되었거나 데이터 변경으로 인해 오래되고 오해의 소지가 있음
  4. Windows 메모리 사용률이 변경됨
  5. 트랜잭션 로그가 가득 차서 잘리지 않아 실제 파일 확장이 반복됩니다
  6. 스키마 변경-색인 / 색인보기 / 열 / 제약 조건 추가, 수정 또는 삭제, 데이터 유형 변경 등
  7. 추적 플래그 설정이 변경됨
  8. Windows 업데이트가 적용되었습니다
  9. 데이터베이스 또는 서버 설정이 변경됨
  10. 서버 CU 레벨이 변경됨
  11. 클라이언트 응용 프로그램 세션 설정이 변경되었습니다.

이 목록의 항목 6-11은 명시 적 조치가 수행 된 후에 만 ​​발생할 수 있습니다. 나는 당신이 그것들을 배제하려고 의도했지만, 도전을 겪고있는 사람들은 다른 누군가가 변경을했는지 알지 못하고 계획 캐시 항목을 지우는 경로를 시작하기 전에 점검 할 가치가 있다고 생각합니다.


1
편집 폴 감사합니다. @sp_BlitzErik-특정 주제에 대한 조언을 제공하려는 의도는 아니며 주제에 대한 인식을 높이고 체크 아웃 할 가치가 있습니다. 이것은 결코 당신의 위대한 지위를 축소시키기위한 것이 아닙니다. 당신은 매개 변수 스니핑을 깊이, 전문적으로, 좋은 유머를 다루었습니다. 나는 그것을 읽는 것을 즐겼다. 나는 여기에 누군가가이 게시물을 방문하여 눈에 띄는 제목에 따라 다른 잠재적 인 원인을 알고 있는지 확인하고 싶습니다. IMHO는 게시물에 가치를 더해 주지만 그래도 삭제하려면 알려주세요.
SQLRaptor

아뇨, 전혀 아닙니다. 나는 누군가에게 부정확하거나 해가되지 않는 답변을 삭제하라고 요구하지 않았습니다. 나는 아직도 당신이 약간의 세부 사항을 추가 할 수 있다고 생각하지만, 그것은 궁극적으로 당신에게 달려 있습니다.
Erik Darling

10

도움이되지 않은 경우 기존 답변에 추가하기 위해 다음날 쿼리가 "갑자기"다르게 동작하는 경우 다음을 확인하십시오.

  • 마지막으로 사용 된 테이블의 구성표가 변경 되었습니까? SSMS의 경우 개체 탐색기에서 서버를 마우스 오른쪽 단추로 클릭하고을 선택할 수 있습니다 Reports → Standard Reports → Schema Changes History.
  • 품목 수가 급격히 증가 했습니까? 사용 된 테이블에 많은 데이터가있을 때 쿼리 속도가 너무 느려질 수 있습니다.
  • 다른 사람이 귀하와 동시에 데이터베이스를 사용하고 있습니까? 서로의 작업을 방해하지 않는 시간대를 선택하십시오.
  • 시스템 통계는 어떻습니까? 서버가 과열되어 CPU를 조절하거나 하드 드라이브에 공간이 부족하거나 스왑 될 수 있습니다. 서버 룸에 화재 나 홍수와 같은 다른 하드웨어 문제가있을 수 있습니다.

7

또 다른 가능성은 인프라 팀이 VMware에서 vMotion과 같은 도구를 사용하고 있으며 SQL 인스턴스를 지원하는 VM이 ​​DBA에 대해 알지 못하고 호스트에서 호스트로 원활하게 이동하고 있다는 것입니다.

이것은 인프라가 아웃소싱되었을 때의 실제 문제입니다 ... 나는 그것에 악몽이 있습니다.

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