SQL Server:如何跟踪CREATE INDEX命令的进度?


36

SQL Server 2014标准版

我已经读过dm_exec_requests中的percent_complete不适用于CREATE INDEX,实际上,percent_complete坚持为0。所以这无济于事。

我目前使用下面的方法,该方法至少向我展示了运动(未阻止创建索引)。但是我不知道我是整个过程的%10还是%99。

我尝试了这里描述的方法:https : //dba.stackexchange.com/a/102545/6229, 但是它显示出明显的错误完成时间(对于60分钟以上的过程,它基本上显示“现在”,即我进入了10分钟) )

我如何获得线索?

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

Answers:


56

我认为以下查询至少可以使您更加接近。它利用了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查找。
布莱恩(Brian)

现在,只要这对
dbo.table

1
顺便说一句,这也很好地监视了实现页面压缩的进度。sys.dm_exec_query_profiles非常酷。
Todd Kleinhans

2
@JonesomeReinstateMonica我刚刚稍微更新了查询。似乎它确实确实通过ALTER INDEX ALL和甚至(部分)捕获了重建操作ALTER TABLE .. REBUILD。请查阅 :-)。
所罗门·鲁茨基

1
嗨,@RoniVered,我刚刚在答案中稍微更新了查询,以便它捕获了非聚集索引重建。我测试了两种类型的命令(虽然不是DBCC,但我只是想到了),并且在SQL Server 2019、2017、2016和2014上进行了测试。它们在所有命令中的工作方式都相同:-)
Solomon Rutzky
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.