我认为以下查询至少可以使您更加接近。它利用了SQL Server 2014中引入的DMV:sys.dm_exec_query_profiles(感谢Martin Smith通过此相关的DBA.StackExchange向我介绍了它):SELECT INTO语句的进度:- 。
请注意:
!! 您将需要添加SET STATISTICS PROFILE ON;
或SET STATISTICS XML ON;
在查询批次是做CREATE INDEX
(和放在之前的CREATE INDEX
说法,如果不明显),否则没有行会在这个DMV显示为SPID / session_id
!!
的IN
运算符用于过滤出Index Insert
的行的是,如果包括的话,会增加TotalRows
值,这将歪斜的计算,因为该行从未示出了处理的任何行。
TotalRows
由于操作分两步进行,因此此处显示的行数(即)是表的行数的两倍,每一步都对所有行进行操作:第一个是“ Table Scan”或“ Clustered Index Scan”,第二个是“排序”。在堆上创建聚簇索引或创建非聚簇索引时,您将看到“表扫描”。在聚簇索引上创建非聚簇索引时,您将看到“聚簇索引扫描”。
创建过滤索引时,该查询似乎不起作用。出于某种原因,筛选索引a)没有“排序”步骤,而b)row_count
字段从0开始永远不会增加。
不知道我在之前的测试,但我现在的测试表明,过滤索引是通过该查询捕获。甜。尽管只是要注意行计数可能会关闭(我将看是否有一天可以解决该问题)。
在已经具有非聚集索引的堆上创建聚簇索引时,需要重建非聚簇索引(以换出RID-RowID-以获得聚簇索引键),并且每次非聚簇索引重建都会是一个单独的操作,因此不会在创建聚簇索引期间反映在此查询返回的统计信息中。
已针对以下查询测试此查询:
- 创建:
- 堆上的非聚集索引
- 聚集索引(不存在非聚集索引)
- 聚集索引/表上的非聚集索引
- 非聚集索引已存在时的聚集索引
- 聚集索引/表上的唯一非聚集索引
- 通过以下方法重建(具有聚集索引和一个非聚集索引的表;已在SQL Server 2014、2016、2017和2019上进行了测试)
ALTER TABLE [schema_name].[table_name] REBUILD;
(使用此方法时仅显示聚集索引)
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查找。