처음부터 내 질문 / 문제 가이 이전 질문과 비슷하다고 말하지만 원인이나 시작 정보가 같은지 확실하지 않기 때문에 질문에 대한 자세한 내용을 게시하기로 결정했습니다.
당면한 문제 :
- (업무 일이 끝날 무렵) 이상한 시간에 프로덕션 인스턴스가 잘못 작동하기 시작합니다.
- 인스턴스의 높은 CPU (기준선에서 ~ 30 %에서 약 두 배로 증가했지만 여전히 증가하고 있음)
- 초당 트랜잭션 수 증가 (앱로드에는 변화가 없지만)
- 유휴 세션 수 증가
- 이 동작을 표시하지 않은 세션 간 이상한 차단 이벤트 (커밋되지 않은 세션을 읽은 경우에도 차단이 발생 함)
- 간격에 대한 상위 대기가 1 위에서 비 페이지 래치였으며 잠금이 2 위를 차지했습니다.
초기 조사 :
- sp_whoIsActive를 사용하여 모니터링 도구에 의해 실행 된 쿼리가 매우 느리게 실행되고 이전에는 발생하지 않았던 CPU를 많이 사용하기로 결정했습니다.
- 격리 수준을 커밋되지 않은 상태로 읽었습니다.
- 약 150TB의 예상 데이터가 반환되는 엉뚱한 숫자 인 StatementEstRows = "3.86846e + 010"을 본 계획을 살펴 보았습니다.
- 모니터링 도구의 쿼리 모니터 기능이 원인 인 것으로 의심되어 해당 기능을 사용하지 않도록 설정했습니다 (제공자에게 문제가 있는지 확인하기 위해 티켓을 열었습니다)
- 첫 번째 사건부터 몇 번 더 일어났습니다. 세션을 종료 할 때마다 모든 것이 정상으로 돌아갑니다.
- 쿼리가 모니터링 저장소 모니터링을 위해 BOL에서 MS에 의해 사용 된 쿼리 중 하나 와 매우 유사하다는 것을 알고 있습니다. 최근에 성능이 저하 된 쿼리 (다른 시점 비교)
- 동일한 쿼리를 수동으로 실행하고 동일한 동작 (CPU 사용 증가, 래치 대기 증가, 예기치 않은 잠금 등)을 확인합니다.
유죄 질의 :
Select qt.query_sql_text,
q.query_id,
qt.query_text_id,
rs1.runtime_stats_id AS runtime_stats_id_1,
interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time),
p1.plan_id AS plan_1,
rs1.avg_duration AS avg_duration_1,
rs2.avg_duration AS avg_duration_2,
p2.plan_id AS plan_2,
interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time),
rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt
Inner Join sys.query_store_query AS q
ON qt.query_text_id = q.query_text_id
Inner Join sys.query_store_plan AS p1
ON q.query_id = p1.query_id
Inner Join sys.query_store_runtime_stats AS rs1
ON p1.plan_id = rs1.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi1
ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id
Inner Join sys.query_store_plan AS p2
ON q.query_id = p2.query_id
Inner Join sys.query_store_runtime_stats AS rs2
ON p2.plan_id = rs2.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi2
ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE())
AND rsi2.start_time > rsi1.start_time
AND p1.plan_id <> p2.plan_id
AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time
설정 및 정보 :
- Windows Server 2012R2 클러스터의 SQL Server 2016 SP1 CU4 Enterprise
- 쿼리 저장소가 활성화되고 기본값으로 구성됨 (설정이 변경되지 않음)
- SQL 2005 인스턴스에서 가져온 데이터베이스 (그리고 여전히 호환성 수준 100)
경험적 관찰 :
- 엉뚱한 통계로 인해, 우리는 잘못된 추정 계획에 사용 된 모든 * plan_persist ** 객체를 가져 왔고 (실제 계획은 아직 쿼리를 완료하지 못함) 통계를 확인했습니다. 계획에 사용 된 일부 인덱스에는 통계가 없었습니다. (DBCC SHOWSTATISTICS가 아무것도 반환하지 않았습니다. sys.stats에서 선택하면 일부 인덱스에 대해 NULL stats_date () 함수가 표시되었습니다.
빠르고 더러운 솔루션 :
- Query Store와 관련된 시스템 개체에 대해 누락 된 통계를 수동으로 생성하거나
- 새로운 CE (traceflag)를 사용하여 쿼리를 강제 실행합니다. 또한 필요한 통계를 생성 / 업데이트하거나
- 데이터베이스의 호환성 수준을 130으로 변경 (기본적으로 새 CE를 사용함)
따라서 내 실제 질문은 다음과 같습니다.
Query Store의 쿼리로 인해 전체 인스턴스에서 성능 문제가 발생하는 이유는 무엇입니까? Query Store에서 버그 영역에 있습니까?
추신 : 일부 파일 (인쇄 화면, IO 통계 및 계획)을 짧은 시간에 업로드합니다.
Dropbox에 추가 된 파일 .
계획 1- 초기 엉뚱한 생산 계획
계획 2- 테스트 환경에서 실제 계획, 오래된 CE (동일한 동작, 엉뚱한 통계)
계획 3- 테스트 환경에서 실제 계획, 새로운 CE