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 しかし、それは明らかに間違った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ます)。そうしないと、このDMVにそのSPIDの行が表示されませんsession_id

  • INオペレータは除外するために使用されIndex Insert、含まれている場合、増加する行TotalRowsその行が処理された行を示すことがないので、計算をゆがめるであろう値を、。

  • ここに表示される行カウント(つまりTotalRows)は、2つのステップを実行する操作のため、テーブルの行カウントの2倍です。各ステップはすべての行で動作します。1つ目は「テーブルスキャン」または「クラスタ化インデックススキャン」、 「ソート」。クラスター化インデックスを作成するか、ヒープに非クラスター化インデックスを作成すると、「テーブルスキャン」が表示されます。クラスタ化インデックスに非クラスタ化インデックスを作成すると、「クラスタ化インデックススキャン」が表示されます。

  • このクエリは、フィルター選択されたインデックスを作成するときに機能しないようです。何らかの理由で、フィルターインデックスにはa) "並べ替え"ステップがありません。b)row_countフィールドが0から増加することはありません。
    以前に何をテストしていたのかはわかりませんが、私のクエリでは、フィルター処理されたインデックスこのクエリによってキャプチャされていることがわかりました。甘い。行カウントがオフになる可能性があることに注意してください(いつか修正できるかどうかを確認します)。

  • 既に非クラスター化インデックスがあるヒープにクラスター化インデックスを作成する場合、(クラスター化インデックスキーのRID-RowID-をスワップアウトするために)非クラスター化インデックスを再構築する必要があり、各非クラスター化インデックスの再構築は別の操作であるため、クラスター化インデックスの作成中にこのクエリによって返される統計には反映されません。

  • このクエリは、以下に対してテストされています。

    • 作成:
      • ヒープ上の非クラスター化インデックス
      • クラスター化インデックス(非クラスター化インデックスは存在しません)
      • クラスター化インデックス/テーブルの非クラスター化インデックス
      • 非クラスター化インデックスが既に存在する場合のクラスター化インデックス
      • クラスター化インデックス/テーブル上の一意の非クラスター化インデックス
    • 再構築(クラスター化インデックスと1つの非クラスター化インデックスを含むテーブル。SQLServer 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設定された演算子を使用します。また、多くのRIDルックアップを実行するため、非常に遅くなります。N'Index Scan'N'Table Scan'N'Clustered Index Scan'
ブライアン

これが、ALTER INDEX ALL ON dbo.table REBUILDで機能する場合にのみ..... <g>
ジョーンズームがモニカを復活

1
ところで、これはページ圧縮の実装の進行状況を監視するのにもうまく機能します。sys.dm_exec_query_profilesはかなりクールです。
トッドクラインハンス

2
@JonesomeReinstateMonicaクエリを少し更新しました。実際、ALTER INDEX ALL(部分的に)経由でも、さらには(一部)再構築操作をキャプチャするようですALTER TABLE .. REBUILD。確認してください:-)。
ソロモンラッツキー

1
こんにちは@RoniVered答えのクエリをわずかに更新して、NonClustered Indexの再構築をキャプチャできるようにしました。(DBCCが、私はそのことを考えていないが)、私は、コマンドの両方のタイプをテストし、SQL Serverの2019年、2017年、2016年、そして2014年にそれらのすべてにわたって同じように動作するようです:-)
ソロモンRutzky
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.