Ich denke, die folgende Abfrage wird Sie zumindest ganz nah bringen. Es wird eine DMV verwendet, die in SQL Server 2014 eingeführt wurde: sys.dm_exec_query_profiles (und danke an Martin Smith für die Einführung über diese verwandte DBA.StackExchange-Antwort: Fortschritt der SELECT INTO-Anweisung :-).
Bitte beachten Sie:
!! Sie müssen den Abfrage-Batch hinzufügen SET STATISTICS PROFILE ON;
oder SET STATISTICS XML ON;
in den Abfrage-Batch einfügen, der den Befehl ausführt CREATE INDEX
(und vor die CREATE INDEX
Anweisung gestellt wird, falls dies nicht offensichtlich ist). Andernfalls werden in dieser DMV keine Zeilen für diese SPID / !! angezeigt.session_id
Der IN
Operator wird verwendet, um die Index Insert
Zeile herauszufiltern, die , falls enthalten, die TotalRows
Werte erhöht , wodurch die Berechnungen verzerrt werden, da in dieser Zeile keine verarbeiteten Zeilen angezeigt werden.
Die hier angezeigte Zeilenzahl (dh TotalRows
) ist doppelt so hoch wie die Zeilenzahl der Tabelle, da zwei Schritte ausgeführt werden, von denen jeder für alle Zeilen ausgeführt wird: der erste ist ein "Tabellenscan" oder "Clustered-Index-Scan" und der zweite ist die Art". Sie sehen "Table Scan", wenn Sie einen Clustered Index oder einen NonClustered Index auf einem Heap erstellen. Sie sehen "Clustered Index Scan", wenn Sie einen NonClustered Index für einen Clustered Index erstellen.
Diese Abfrage scheint beim Erstellen von gefilterten Indizes nicht zu funktionieren. Aus irgendeinem Grund haben gefilterte Indizes a) nicht den Schritt "Sortieren", und b) das row_count
Feld steigt nie von 0 an.
Nicht sicher , was ich zu testen , bevor, aber meine Tests nun zeigen , dass Filtered Indizes werden von dieser Abfrage erfasst. Süss. Beachten Sie jedoch, dass die Zeilenzählung möglicherweise deaktiviert ist (ich werde sehen, ob ich das eines Tages beheben kann).
Wenn Sie einen Clustered-Index auf einem Heap erstellen, auf dem sich bereits NonClustered-Indizes befinden, müssen die NonClustered-Indizes neu erstellt werden (um die RID (RowID) gegen die Clustered-Index-Schlüssel auszutauschen) eine separate Operation sein und sich daher nicht in den Statistiken widerspiegeln, die von dieser Abfrage während der Erstellung des Clustered Index zurückgegeben werden.
Diese Abfrage wurde getestet gegen:
- Erstellen:
- NonClustered-Indizes auf einem Heap
- ein Clustered-Index (keine NonClustered-Indizes vorhanden)
- NonClustered-Indizes für den Clustered-Index / die Clustered-Tabelle
- ein Clustered-Index, wenn bereits NonClustered-Indizes vorhanden sind
- Eindeutige NonClustered-Indizes für den Clustered-Index / die Clustered-Tabelle
- Neuerstellung (Tabelle mit Clustered Index und einem NonClustered Index; getestet auf SQL Server 2014, 2016, 2017 und 2019) über:
ALTER TABLE [schema_name].[table_name] REBUILD;
( Bei dieser Methode wird nur der Clustered Index angezeigt. )
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;
Beispielausgabe:
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
WertN'Index Scan'
, anstattN'Table Scan'
oderN'Clustered Index Scan'
. Außerdem wird es sehr langsam sein, da es eine Reihe von RID-Suchen durchführen wird.ALTER INDEX ALL
als auch (teilweise)ALTER TABLE .. REBUILD
. Lesen Sie bitte :-).