IndexOptimize 후 쿼리 및 업데이트 속도가 매우 느림


12

데이터베이스 SQL Server 2017 Enterprise CU16 14.0.3076.1

우리는 최근에 기본 인덱스 재 구축 유지 보수 작업에서 Ola Hallengren으로 전환을 시도했습니다 IndexOptimize. 기본 인덱스 재 구축 작업이 아무런 문제없이 몇 달 동안 실행되었으며 쿼리와 업데이트가 적절한 실행 시간으로 작동했습니다. IndexOptimize데이터베이스에서 실행 한 후 :

EXECUTE dbo.IndexOptimize
@Databases = 'USER_DATABASES',
@FragmentationLow = NULL,
@FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationLevel1 = 5,
@FragmentationLevel2 = 30,
@UpdateStatistics = 'ALL',
@OnlyModifiedStatistics = 'Y'

성능이 크게 저하되었습니다. 100ms IndexOptimize가 걸리던 업데이트 문은 이후 동일한 계획을 사용하여 78.000ms가 걸렸으며 쿼리도 몇 배나 더 나빴습니다.

이 데이터베이스는 여전히 테스트 데이터베이스이므로 (Oracle에서 프로덕션 시스템을 마이그레이션하고 있음) 백업으로 IndexOptimize되돌리고 비활성화 하고 모든 것이 정상으로 돌아 왔습니다.

그러나 일단 생산에 들어가면 피할 수 있도록 이러한 성능 저하를 유발할 수 IndexOptimize있는 "정상"과 다른 점 을 이해하고 싶습니다 Index Rebuild. 찾아야 할 것에 대한 제안은 크게 감사하겠습니다.

업데이트 명령문이 느릴 때 실행 계획. 즉,
IndexOptimize
실제 실행 계획 (가능한 빨리)

나는 차이를 발견 할 수 없었다.
빠른 경우 동일한 쿼리
계획 실제 실행 계획

답변:


11

두 가지 유지 관리 방법 사이에 다른 샘플 속도가 정의되어 있다고 생각합니다 . @StatisticsSample매개 변수 를 지정하지 않으면 Ola의 스크립트가 기본 샘플링을 사용한다고 생각 합니다. 현재 수행하지 않는 것처럼 보입니다.

이 시점에서 이것은 추측이지만 데이터베이스에서 다음 쿼리를 실행하여 통계에서 현재 사용중인 샘플링 속도를 확인할 수 있습니다.

SELECT  OBJECT_SCHEMA_NAME(st.object_id) + '.' + OBJECT_NAME(st.object_id) AS TableName
    ,   col.name AS ColumnName
    ,   st.name AS StatsName
    ,   sp.last_updated
    ,   sp.rows_sampled
    ,   sp.rows
    ,   (1.0*sp.rows_sampled)/(1.0*sp.rows) AS sample_pct
FROM sys.stats st 
    INNER JOIN sys.stats_columns st_col
        ON st.object_id = st_col.object_id
        AND st.stats_id = st_col.stats_id
    INNER JOIN sys.columns col
        ON st_col.object_id = col.object_id
        AND st_col.column_id = col.column_id
    CROSS APPLY sys.dm_db_stats_properties (st.object_id, st.stats_id) sp
ORDER BY 1, 2

이것이 1 초 (예 : 100 %)의 기회를 통해 온다면 이것이 문제입니다. 어쩌면 @StatisticsSample이 쿼리에서 반환되는 백분율이 포함 된 매개 변수를 포함하여 Ola의 스크립트를 다시 시도 하고 문제가 해결되는지 확인하십시오.


이 이론에 대한 추가 지원 증거로서 실행 계획 XML은 느린 쿼리에 대한 샘플링 속도가 크게 다릅니다 (2.18233 %).

<StatisticsInfo LastUpdate="2019-09-01T01:07:46.04" ModificationCount="0" 
    SamplingPercent="2.18233" Statistics="[INDX_UPP_4]" Table="[UPPDRAG]" 
    Schema="[SVALA]" Database="[ulek-sva]" />

빠른 쿼리와 비교 (100 %) :

<StatisticsInfo LastUpdate="2019-08-25T23:01:05.52" ModificationCount="555" 
    SamplingPercent="100" Statistics="[INDX_UPP_4]" Table="[UPPDRAG]" 
    Schema="[SVALA]" Database="[ulek-sva]" />

@ JoshDarnell LOL, 이것은 내가 보지 못한 쿼리 계획에서 지원 통계 정보를 찾은 두 번째 사건 입니다. 편집 해 주셔서 감사합니다!
John Eisbrener

하하 나는 너라는 것을 잊었다. 존! 나는 당신을 스토킹하지 않겠다고 약속합니다.
Josh Darnell

@JoshDarnell 추가 통찰력에 감사 드리며 실행 계획에 건너 뛰면 안되는 정보가 너무 많다는 것을 다시 한 번 상기시켜줍니다.
John Eisbrener

기쁘다! 그리고 네, 항상 그리워하는 것들이 있습니다 (통계에 의해 불에 탔기 때문에 나는 무슨 일이 일어나고 있는지 빨리 보려고합니다).
Josh Darnell

이 설명에 감사드립니다. 실제로 문제였습니다. 대부분의 통계는 기본 샘플링 속도가 2.2 %이지만 Oracle에서 마이그레이션 한 후 생성 된 일부는 샘플링 속도가 100 %입니다. 기본 인덱스 재 구축은 100 %를 유지 한 것으로 보이지만 IndexOptimize를 사용하면 기본 인덱스도 2.2 %를 적용했습니다. @StatisticsSample 매개 변수를 적용하고 쿼리를 다시 실행하면 이것이 문제의 원인인지 확인했습니다.
Martin Bergström

5

John의 대답 은 올바른 해결책입니다. 이것은 실행 계획의 일부가 변경된 부분에 대한 추가 사항이며 Sentry One Plan 탐색기로 차이점을 쉽게 발견하는 방법에 대한 예입니다.

IndexOptimize가 100.78ms가 걸리기 전에 100ms가 걸리는 업데이트 설명 (동일한 계획을 사용하여)

성능이 저하 된 모든 쿼리 계획을 살펴보면 차이점을 쉽게 파악할 수 있습니다.

성능 저하

여기에 이미지 설명을 입력하십시오

35 초 이상의 CPU 시간 및 경과 시간 2 카운트

기대 성능

여기에 이미지 설명을 입력하십시오

훨씬 낫다

주요 업데이트는이 업데이트 쿼리에서 두 번입니다.

UPDATE SVALA.INGÅENDEANALYS
                           SET 
                              UPPDRAGAVSLUTAT = @NEW$AVSLUTAT
                        WHERE INGÅENDEANALYS.ID IN 
                           (
                              SELECT IA.ID
                              FROM 
                                 SVALA.INGÅENDEANALYS  AS IA 
                                    JOIN SVALA.INGÅENDEANALYSX  AS IAX 
                                    ON IAX.INGÅENDEANALYS = IA.ID 
                                    JOIN SVALA.ANALYSMATERIAL  AS AM 
                                    ON AM.ID = IA.ANALYSMATERIALID 
                                    JOIN SVALA.ANALYSMATERIALX  AS AMX 
                                    ON AMX.ANALYSMATERIAL = AM.ID 
                                    JOIN SVALA.INSÄNTMATERIAL  AS IM 
                                    ON IM.ID = AM.INSÄNTMATERIALID 
                                    JOIN SVALA.INSÄNTMATERIALX  AS IMX 
                                    ON IMX.INSÄNTMATERIAL = IM.ID
                              WHERE IM.UPPDRAGSID = SVALA.PKGSVALA$STRIPVERSION(@NEW$ID)
                      )

성능이 저하 된이 쿼리의 실행 계획

이 업데이트 쿼리의 예상 쿼리 계획은 성능이 저하 될 때 예상치가 매우 높습니다.

여기에 이미지 설명을 입력하십시오

실제로 (실제 실행 계획) 실제로는 추정치가 보여주는 미친 양이 아니라 여전히 작동해야합니다.

성능에 가장 큰 영향은 아래의 두 스캔 및 해시 일치 조인입니다.

성능 저하 # 1에 대한 실제 스캔

여기에 이미지 설명을 입력하십시오

성능 저하 # 2에 대한 실제 스캔

여기에 이미지 설명을 입력하십시오


예상 성능을 가진이 쿼리의 실행 계획

정상적인 예상 성능을 가진 쿼리 계획의 추정치 (또는 실제)와 비교하면 차이점을 쉽게 알 수 있습니다.

여기에 이미지 설명을 입력하십시오

또한 이전 두 테이블 액세스는 발생하지 않았습니다.

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

빌드 (상단) 입력이 먼저 해시 테이블에 삽입되므로 해시 조인에서이 제거가 표시되지 않습니다. 이후이 해시 테이블에서 0 값이 검색되어 0 값이 반환됩니다.


1
계획에 대한 자세한 설명을 주셔서 감사합니다. 문제가 발생한 이유를 이해하는 데 큰 도움이되었습니다. Sentry One Plan Explorer를 확실히 살펴볼 것입니다. 매우 유용합니다!
Martin Bergström

@ MartinBergström 들려 주셔서 감사합니다. 질의 계획을 제공하고 의견에서 요청한 모든 관련 정보를 제공해 주셔서 감사합니다. :). 계획 탐색기의 가장 좋은 점은 무료라는 것입니다! 또한 실행 계획을 마우스 오른쪽 단추로 클릭하고 "Sterryone 계획 탐색기로보기"를 눌러 ssms 내부에서 작동 할 수도 있습니다.
Randi Vertongen

1

더 많은 정보가 없으면 어두운 곳에서만 가볍게 찌를 수 있으므로 질문을 편집하여 조금 더 제공해야합니다. 예를 들어 인덱스 통계가 업데이트되어 계획이 다를 수 있으므로 인덱스 유지 관리 작업 전후에 타이밍을 제공 한 해당 업데이트 문의 쿼리 계획 ( https://www.brentozar.com/pastetheplan / 는 XML의 거대한 덩어리로 질문을 채우거나 계획의 텍스트에 포함 된 관련 정보가 포함되지 않은 화면을 제공하는 것보다 유용합니다.

박쥐의 두 가지 매우 간단한 점 :

  1. 최적화 실행이 확실히 완료 되었습니까? 테스트가 타이밍에 영향을 미치는 장기 실행 인덱스 재 구축의 IO와 경쟁하는 경우.
  2. 여러 번 테스트 했습니까? 업데이트가 간단한`UPDATE TheTable SET ThisColumn = 'A 정적 값'이 아닌 많은 데이터를 고려하는 쿼리의 데이터를 기반으로하는 경우이 데이터는 일반적으로 메모리에 있지만 플러시 된 것일 수 있습니다. 관련 쿼리의 첫 번째 실행은 때문에 디스크 타격보다는 메모리에 버퍼 풀에 이미 필요한 페이지를 찾는 느린 평소보다.

답장을 보내 주셔서 감사합니다. pastetheplan 링크로 질문을 업데이트했습니다. 최적화는 문제가 발생하기 전날 약 1 시간 동안 실행되었습니다. 우리는 여러 번 테스트했으며 실제로 동일한 방식으로 서로 다른 두 가지 테스트 환경에서 실행되는 두 개의 데이터베이스 복사본에 영향을 미쳤습니다. 업데이트 문은, 다른 많은 삽입과 선택이 있었다 내가 찾은 그냥 간단한 예를했다 영향
마틴 버그 스트롬

"여러 번"이란 인덱스 최적화 스크립트를 독립적으로 여러 번 실행하지 않고 인덱스 변경 한 인스턴스 후에 여러 번 업데이트를 시도하는 것을 의미했습니다 (결과 자체를 재현 할 수있는 유용한 방법 임). 메모리 플러싱이 문제 (또는 그 일부) 인 경우, 첫 번째 선택에서 업데이트가 버퍼 풀을 프라이밍하므로 나중에 업데이트 된 IO가 크게 감소하여 잠재적으로 더 빠릅니다.
David Spillett

내 답변이 명확하지 않은 경우 사과드립니다. 예, 업데이트를 여러 번 시도했습니다. 성능 저하없이 하루 동안 여러 번 실행되는 응용 프로그램 및 쿼리 및 업데이트를 테스트하기 위해 테스터가 사용하는 데이터베이스에서 속도 저하가 발생했습니다.
마틴 버그 스트롬
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.