다음 쿼리는 적어도 당신을 아주 가깝게 만들 것이라고 생각합니다. 그것은 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 조회를 수행하기 때문에 속도가 매우 느립니다.