이전에 빠른 SQL 쿼리가 느리게 실행되면 문제의 원인을 어디서 찾을 수 있습니까?


36

배경

약 12 개의 "테이블"에 조인 및 / 또는 왼쪽 조인하는 SQL Server 2008 R2에 대해 실행중인 쿼리가 있습니다. 데이터베이스는 5 천만 개가 넘는 테이블과 약 300 개의 서로 다른 테이블이있는 상당히 큽니다. 전국에 10 개의 창고가있는 대기업입니다. 모든웨어 하우스는 데이터베이스를 읽고 씁니다. 꽤 크고 바쁩니다.

문제가있는 쿼리는 다음과 같습니다.

select t1.something, t2.something, etc.
from Table1 t1
    inner join Table2 t2 on t1.id = t2.t1id
    left outer join (select * from table 3) t3 on t3.t1id = t1.t1id
    [etc]...
where t1.something = 123

조인 중 하나는 상관되지 않은 하위 쿼리에 있습니다.

문제는 오늘 아침, 시스템에 대한 변경 (나 또는 팀원 모두가 알고 있음)없이 실행하는 데 일반적으로 약 2 분이 걸리고 실행하는 데 1 시간 반이 걸리는 쿼리입니다. 전혀 달렸다. 나머지 데이터베이스는 잘 작동합니다. 나는 일반적으로 실행되는 sproc 에서이 쿼리를 가져 와서 동일한 속도로 하드 코딩 된 매개 변수 변수를 사용하여 SSMS에서 실행했습니다.

이상한 점은 상관되지 않은 하위 쿼리를 가져 와서 임시 테이블에 넣은 다음 하위 쿼리 대신 해당 쿼리를 사용하면 쿼리가 제대로 실행된다는 것입니다. 또한이 코드를 쿼리 끝에 추가하면 쿼리가 훌륭하게 실행됩니다.

and t.name like '%'

이 작은 실험에서 느려진 이유는 SQL의 캐시 실행 계획이 설정되는 방식 때문이라고 결론을 내 렸습니다. 조회가 약간 다르면 새로운 실행 계획을 만들어야합니다.

내 질문은 이것입니다 : 빠른 실행에 사용 된 쿼리가 갑자기 한밤중에 느리게 실행되기 시작 하고이 하나의 쿼리를 제외하고 다른 영향을받지 않으면 어떻게 문제를 해결하고 향후에 발생하지 않게합니까 ? SQL이 느리게 만들기 위해 SQL이 내부적으로 수행하는 작업을 어떻게 알 수 있습니까? (잘못된 쿼리가 실행되면 실행 계획을 얻을 수는 있지만 실행되지 않습니다. 예상되는 실행 계획이 나에게 뭔가를 줄 수 있습니까?) 이 문제가 실행 계획과 관련이있는 경우 SQL이 실제로 실행 계획이 좋은 아이디어라고 생각하지 않도록하려면 어떻게해야합니까?

또한 이것은 매개 변수 스니핑에 문제가되지 않습니다. SSMS에서 변수를 하드 코딩 할 때도 여전히 성능이 저하되기 때문에 이전에 보았지만 이것이 아닙니다.


여기 쿼리 계획 (느린 하나를) 공유 할 수 없습니다 : brentozar.com/pastetheplan
MJH에게

답변:


31

빠른 실행에 사용 된 쿼리가 갑자기 한밤중에 느리게 실행되기 시작하고이 쿼리를 제외하고 다른 영향을받지 않으면 어떻게 문제를 해결합니까?

실행 계획이 여전히 캐시에 있는지 확인하여 시작할 수 있습니다. 확인 sys.dm_exec_query_stats, sys.dm_exec_procedure_statssys.dm_exec_cached_plans. 잘못된 실행 계획이 여전히 캐시되어 있으면이를 분석하고 실행 통계를 확인할 수도 있습니다. 실행 통계에는 논리적 읽기, CPU 시간 및 실행 시간으로 정보가 포함됩니다. 이는 문제가 무엇인지에 대한 강력한 표시를 제공 할 수 있습니다 (예 : 큰 스캔 대 차단). 데이터 해석 방법에 대한 설명은 문제점 쿼리 식별을 참조 하십시오 .

또한 이것은 매개 변수 스니핑에 문제가되지 않습니다. SSMS에서 변수를 하드 코딩 할 때도 여전히 성능이 저하되기 때문에 이전에 보았지만 이것이 아닙니다.

나는 확신하지 못한다. SSMS의 하드 코딩 변수는 과거 잘못된 실행 계획이 왜곡 된 입력에 대해 컴파일되지 않았 음을 증명하지 않습니다. 주제에 대한 훌륭한 기사를 보려면 매개 변수 스니핑, 임베딩 및 권장 옵션 을 읽으십시오 . 응용 프로그램이 느리고 SSMS가 빠릅니까? 성능 미스터리 이해 는 또 다른 훌륭한 참고 자료입니다.

이 작은 실험에서 느려진 이유는 SQL의 캐시 실행 계획이 설정되는 방식 때문이라고 결론을 내 렸습니다. 조회가 약간 다르면 새로운 실행 계획을 만들어야합니다.

이것은 쉽게 테스트 할 수 있습니다. SET STATISTICS TIME ON컴파일 시간과 실행 시간을 보여줍니다. SQL Server : Statistics 성능 카운터는 컴파일이 문제인지 여부를 공개합니다 (솔직히, 가능성이 적습니다).

그러나 쿼리 그랜트 게이트 (Grant Grant Gate)와 유사한 것이 있습니다. 자세한 내용은 SQL Server 메모리 부여 이해를 읽으십시오 . 쿼리에서 사용 가능한 메모리가없는 순간에 많은 양의 승인을 요청하는 경우 대기해야하며 모두 응용 프로그램에 대한 '느린 실행'으로 보입니다. 대기 정보 통계 를 분석 하면 이것이 사실인지 알 수 있습니다.

측정 대상과 찾을 대상에 대한 일반적인 내용은 SQL Server 성능 분석 방법을 참조하십시오.


7

이것은 SQL Server에서 복잡한 쿼리를 실행하는 데 어려움이 있습니다. 다행히도 자주 발생하지 않습니다.

쿼리에 대한 쿼리 계획을 살펴보십시오 (느리게 실행되는 경우). 조인에 대한 인덱스가없는 테이블에서 중첩 루프 조인이 한 번 이상 발생한다는 것을 알았습니다. 이로 인해 실제로 속도가 느려집니다. 빨리 고치기 위해 이것을 고치는 방법은 힌트입니다. 쿼리 끝에 다음을 추가하십시오.

OPTION (MERGE JOIN, HASH JOIN)

이것은 일반적으로 과거 에이 문제를 해결했습니다.

일어날 수있는 일은 테이블에 대한 미묘한 변경 (또는 임시 공간의 가용성)으로 인해 SQL 최적화가 느린 결합 알고리즘을 선호한다는 것입니다. 이것은 매우 미묘하고 갑작 스러울 수 있습니다. 임시 테이블을 작성할 때 옵티마이 저는 테이블에 대한 자세한 정보 (예 : 크기)를 가지므로 더 나은 계획을 생성 할 수 있습니다.


1
실행 계획은 실제로 중첩 루프 조인을 사용합니다. 그러나 제안한대로 힌트를 배치하면 "이 쿼리에 정의 된 힌트로 인해 쿼리 프로세서에서 쿼리 계획을 생성 할 수 없습니다. 힌트를 지정하지 않고 SET FORCEPLAN을 사용하지 않고 쿼리를 다시 제출하십시오."라는 오류가 발생합니다. 물론 OPTION (LOOP JOIN)을 추가하면 실행 계획이 생성되지만 여전히 느리게 실행되는 데 문제가 있습니다. 이 문제가 발생 했습니까? 루프 조인이 필요하다고 생각되는 것 같습니다.

@ 트레버. . . 아니요, 실제로이 문제를 보지 못했습니다. 아마도 귀하의 쿼리가 등호를 사용하지 않는 일부 비 평형을 수행하고 있으며 옵티마이 저는 중첩 루프 조인을 사용해야합니다.
Gordon Linoff

3

일반적으로 색인이 누락되어 이런 종류의 문제가 발생합니다.

일반적으로 SQL Management Studio를 사용하여 쿼리를 실행하고 '실제 실행 계획 포함 (CTRL + M)'을 활성화하고 어느 조인이 가장 큰 비율인지 확인합니다.

응용 프로그램은 병목 현상에 초점을 맞추지 않지만 결과를 "빠르게"찾을 수 있습니다.

여기 예 : 48 퍼센트


2
그러나 인덱스가 갑자기 "누락"되지는 않으므로 성능이 향상 될 수 있지만 문제를 설명하지는 않습니다.
Fowl

3

최근에 같은 문제가 발생하여이 페이지로 연결되었습니다.

@MartinSmith는 통계 업데이트 및 계획 설명을 권장 할 때 문제가 발생했습니다. 또한 잠금을 생성하여 응답 시간을 느리게 할 수있는 작업 / 쿼리 실행을 살펴보아야합니다.

제 경우에는 범인이 직업 수집 테이블 통계였습니다. 어떤 이유로 창에서 완료되지 않았으며 사용자가 다시 시작했을 때 계속 실행되었습니다. 프로세스를 발견하고 종료했으며 쿼리가 다시 응답하기 시작했습니다.

나는 이것이 다른 누군가를 돕기를 바랍니다.


0

또한 T-SQL \ Procedure에서 성능 문제가 발생하면 서버 백업 또는 보관 / 인덱싱 작업이 실행 중인지 확인해야합니다.

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