SQL Server : CREATE INDEX 명령의 진행 상황을 추적하는 방법?


36

SQL Server 2014, 표준 Ed

dm_exec_requests의 percent_complete가 CREATE INDEX에서 작동하지 않으며 실제로 percent_complete는 0에 붙어 있다는 것을 읽었습니다. 그래서 도움이되지 않습니다.

현재 아래 방법을 사용합니다.이 방법은 적어도 움직임을 보여줍니다 (색인 생성이 차단되지 않음). 그러나 프로세스 또는 % 99를 통해 % 10인지 알 수 없습니다.

나는 여기에 설명 된 방법을 시도했다 : /dba//a/102545/6229 그러나 그것은 분명히 잘못된 est 완료 시간을 보여줍니다. )

실마리를 얻으려면 어떻게해야합니까?

SELECT percent_complete, estimated_completion_time, reads, writes, logical_reads, text_size, *
FROM
sys.dm_exec_requests AS r
WHERE
r.session_id <> @@SPID
AND r.session_id = 58

답변:


56

다음 쿼리는 적어도 당신을 아주 가깝게 만들 것이라고 생각합니다. 그것은 SQL Server 2014에 도입 된 DMV를 사용합니다 : sys.dm_exec_query_profiles (이 관련 DBA.StackExchange 답변 : SELECT INTO 문의 진행 :-) 를 통해 나에게 소개해 준 Martin Smith에게 감사드립니다 .

참고 사항 :

  • !! 당신은 추가해야합니다 SET STATISTICS PROFILE ON;또는 SET STATISTICS XML ON;쿼리 일괄 즉를하고있다 CREATE INDEX(그리고 배치 하기 전에CREATE INDEX / 다른 행이 그 SPID이 DMV에 표시되지 않습니다, 그것은 분명 아니었다면, 문) session_id !

  • IN연산자는 Index Insert포함 된 경우 TotalRows값 을 증가시키는 행 을 필터링하는 데 사용되며 ,이 행은 처리 된 행을 표시하지 않으므로 계산이 왜곡됩니다.

  • 여기에 표시된 행 수 (예 :) TotalRows는 두 단계를 수행하는 조작으로 인해 테이블의 행 수의 두 배입니다. 각 행은 모두 모든 행에서 작동합니다. 첫 번째는 "테이블 스캔"또는 "클러스터 된 인덱스 스캔"이고 두 번째는 "정렬". 클러스터형 인덱스를 만들거나 힙에 비 클러스터형 인덱스를 만들 때 "테이블 스캔"이 나타납니다. 클러스터형 인덱스에서 비 클러스터형 인덱스를 만들 때 "클러스터형 인덱스 검색"이 나타납니다.

  • 필터링 된 인덱스를 만들 때이 쿼리가 작동하지 않는 것 같습니다. 어떤 이유로 필터링 된 인덱스 a)에는 "정렬"단계가 없으며 b) row_count필드가 0에서 증가하지 않습니다.
    내가 전에 테스트를했지만, 내 테스트는 현재 필터링 된 인덱스는 것을 나타냅니다 확실하지 무엇을 하는 이 쿼리에 의해 캡처. 단. 행 개수가 꺼져있을 수 있음을 유의하십시오 (언젠가 고칠 수 있는지 알 수 있습니다).

  • 비 클러스터형 인덱스가 이미있는 힙에서 클러스터형 인덱스를 생성 할 때 비 클러스터형 인덱스를 다시 작성해야합니다 (클러스터형 인덱스 키의 경우 RID-RowID-를 교체하려면). 각 비 클러스터형 인덱스 다시 작성 별도의 작업이어야하므로 클러스터형 인덱스를 만드는 동안이 쿼리에서 반환 한 통계에 반영되지 않습니다.

  • 이 쿼리는 다음에 대해 테스트되었습니다.

    • 작성 :
      • 힙의 비 클러스터형 인덱스
      • 클러스터형 인덱스 (비 클러스터형 인덱스가 없음)
      • 클러스터형 인덱스 / 테이블의 비 클러스터형 인덱스
      • 비 클러스터형 인덱스가 이미 존재하는 경우 클러스터형 인덱스
      • 클러스터형 인덱스 / 테이블의 고유 한 비 클러스터형 인덱스
    • 다음을 통해 재 구축 (클러스터형 인덱스 및 하나의 비 클러스터형 인덱스로 테이블, SQL Server 2014, 2016, 2017 및 2019에서 테스트)
      • ALTER TABLE [schema_name].[table_name] REBUILD;( 이 방법을 사용하면 Clustered Index 만 나타납니다 )
      • ALTER INDEX ALL ON [schema_name].[table_name] REBUILD;
      • ALTER INDEX [index_name] ON [schema_name].[table_name] REBUILD;
DECLARE @SPID INT = 51;

;WITH agg AS
(
     SELECT SUM(qp.[row_count]) AS [RowsProcessed],
            SUM(qp.[estimate_row_count]) AS [TotalRows],
            MAX(qp.last_active_time) - MIN(qp.first_active_time) AS [ElapsedMS],
            MAX(IIF(qp.[close_time] = 0 AND qp.[first_row_time] > 0,
                    [physical_operator_name],
                    N'<Transition>')) AS [CurrentStep]
     FROM sys.dm_exec_query_profiles qp
     WHERE qp.[physical_operator_name] IN (N'Table Scan', N'Clustered Index Scan',
                                           N'Index Scan',  N'Sort')
     AND   qp.[session_id] = @SPID
), comp AS
(
     SELECT *,
            ([TotalRows] - [RowsProcessed]) AS [RowsLeft],
            ([ElapsedMS] / 1000.0) AS [ElapsedSeconds]
     FROM   agg
)
SELECT [CurrentStep],
       [TotalRows],
       [RowsProcessed],
       [RowsLeft],
       CONVERT(DECIMAL(5, 2),
               (([RowsProcessed] * 1.0) / [TotalRows]) * 100) AS [PercentComplete],
       [ElapsedSeconds],
       (([ElapsedSeconds] / [RowsProcessed]) * [RowsLeft]) AS [EstimatedSecondsLeft],
       DATEADD(SECOND,
               (([ElapsedSeconds] / [RowsProcessed]) * [RowsLeft]),
               GETDATE()) AS [EstimatedCompletionTime]
FROM   comp;

샘플 출력 :

                        Rows                 Percent   Elapsed  Estimated    Estimated
CurrentStep  TotalRows  Processed  RowsLeft  Complete  Seconds  SecondsLeft  CompletionTime
-----------  ---------  ---------  --------  --------  -------  -----------  --------------
Clustered    11248640   4786937    6461703   42.56     4.89400  6.606223     2016-05-23
Index Scan                                                                   14:32:40.547

당신은 힙에 클러스터되지 않은 인덱스를 생성하고 새로운 인덱스가 기존 인덱스와 같은 키가있는 경우, 쿼리와 연산자를 사용하게됩니다 physical_operator_name에 설정을 N'Index Scan'하기보다는 N'Table Scan'N'Clustered Index Scan'. 또한 많은 RID 조회를 수행하기 때문에 속도가 매우 느립니다.
Brian

만약 그것이 dbo.table에 대한 ALTER INDEX ALL에서 작동한다면 ..... <g>
Jonesome Reinstate Monica

1
BTW, 이것은 또한 페이지 압축 구현 진행 상황을 모니터링하는 데에도 효과적입니다. sys.dm_exec_query_profiles는 매우 멋집니다.
Todd Kleinhans

2
@JonesomeReinstateMonica 방금 쿼리를 약간 업데이트했습니다. 그것은 비아 ALTER INDEX ALL와 심지어 (부분적으로) 재건 작업을 실제로 캡처하는 것처럼 보입니다 ALTER TABLE .. REBUILD. 검토하시기 바랍니다 :-).
Solomon Rutzky

1
안녕하세요 @RoniVered 방금 NonClustered Index 재 구축을 캡처하도록 응답에서 쿼리를 약간 업데이트했습니다. 나는 명령의 두 가지 유형 (아니지만 DBCC, 나는 그냥 생각), 테스트 및 SQL 서버 2019, 2017, 2016에, 2014 :-) 모두에 걸쳐 동일하게 작동하는 것 같다
솔로몬 Rutzky
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.