次のクエリは、少なくともあなたをかなり近づけると思います。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'