web-dev-qa-db-ja.com

SQL Server:CREATE INDEXコマンドの進行状況を追跡する方法

SQL Server 2014、Std Ed

私は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

次のクエリを実行すると、少なくともかなり近づくことができると思います。 SQL Server 2014で導入されたDMVを利用します: sys.dm_exec_query_profiles (そして、この関連するDBAを介して私に紹介してくれたMartin Smithに感謝します。StackExchange回答: SELECTの進行状況INTOステートメント :-)。

ご注意ください:

  • !!SET STATISTICS PROFILE ON;を実行しているクエリバッチにSET STATISTICS XML ON;またはCREATE INDEXを追加する必要があります(そしてbeforeCREATE INDEXステートメント(明確でない場合)、そうでない場合、そのSPID/session_id!!の行はこのDMVに表示されません。

  • IN演算子はIndex Insert行を除外するために使用され、含まれている場合はTotalRows値が増加します。この行は、処理された行を表示しないため、計算を歪めます。

  • ここに表示される行数(つまりTotalRows)は、操作が2つのステップを実行するため、テーブルの行数の2倍になり、それぞれがすべての行で操作されます。最初は「テーブルスキャン」または「クラスタ化インデックス」です。スキャン」、2番目は「ソート」です。クラスター化インデックスを作成するとき、またはヒープ上に非クラスター化インデックスを作成するときに、「テーブルスキャン」が表示されます。クラスタ化インデックス上に非クラスタ化インデックスを作成すると、「クラスタ化インデックススキャン」が表示されます。

  • このクエリは、フィルター選択されたインデックスを作成するときに機能しないようです。何らかの理由で、フィルター処理されたインデックスには、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
69
Solomon Rutzky

このトピックはまだアクティブなようですので、SQL Server 2019およびAzure SQL DB(150互換モード)で新しい 再開可能なインデックス操作 を使用すると、この機能が提供されることに注意する価値があると思いました。カタログビュー sys.index_resumable_operations には、進捗状況を示すpercent_complete列があります。

インデックスの作成と再構築を監視できることに加えて、再開可能なインデックス操作は、操作が進行するにつれてコミットされる小さなチャンクに操作を分割することによっても役立ちます。これは、トランザクションログを小さく保つのに役立ちます。また、操作を任意のセカンダリサーバーに複製できるため、可用性グループなどにも役立ちます。再開可能なインデックス操作を使用すると、フェイルオーバー後に進行状況を失うことなく新しいプライマリサーバーでインデックスの作成または再構築を再開できます。トランザクションは途中でコミットされるため、長いインデックス操作中にバックアップの同期の問題は発生しません。 。

2
Pam Lahoud