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-を交換するため)。各非クラスター化インデックスの再構築は別の操作であるため、クラスター化インデックスの作成中にこのクエリによって返される統計には反映されません。
このクエリは、以下に対してテストされています。
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
このトピックはまだアクティブなようですので、SQL Server 2019およびAzure SQL DB(150互換モード)で新しい 再開可能なインデックス操作 を使用すると、この機能が提供されることに注意する価値があると思いました。カタログビュー sys.index_resumable_operations には、進捗状況を示すpercent_complete列があります。
インデックスの作成と再構築を監視できることに加えて、再開可能なインデックス操作は、操作が進行するにつれてコミットされる小さなチャンクに操作を分割することによっても役立ちます。これは、トランザクションログを小さく保つのに役立ちます。また、操作を任意のセカンダリサーバーに複製できるため、可用性グループなどにも役立ちます。再開可能なインデックス操作を使用すると、フェイルオーバー後に進行状況を失うことなく新しいプライマリサーバーでインデックスの作成または再構築を再開できます。トランザクションは途中でコミットされるため、長いインデックス操作中にバックアップの同期の問題は発生しません。 。