Je pense que la requête suivante vous permettra au moins de vous rapprocher. Il utilise un DMV qui a été introduit dans SQL Server 2014: sys.dm_exec_query_profiles (et merci à Martin Smith de me l'avoir présenté via ce DBA.StackExchange Answer: Progression de l'instruction SELECT INTO :-).
Notez s'il vous plaît:
!! Vous devrez ajouter SET STATISTICS PROFILE ON;
ou SET STATISTICS XML ON;
dans le lot de requêtes qui fait le CREATE INDEX
(et placé avant l' CREATE INDEX
instruction, si ce n'était pas évident), sinon aucune ligne n'apparaîtra dans ce DMV pour ce SPID / session_id
!!
L' IN
opérateur est utilisé pour filtrer la Index Insert
ligne qui, si elle est incluse, augmentera les TotalRows
valeurs, ce qui faussera les calculs puisque cette ligne n'affiche jamais aucune ligne traitée.
Le nombre de lignes affiché ici (c.-à-d. TotalRows
) Est le double du nombre de lignes de la table en raison de l'opération prenant deux étapes, chacune opérant sur toutes les lignes: la première est une "analyse de table" ou "analyse d'index en cluster", et la seconde est le genre". Vous verrez «Table Scan» lors de la création d'un index clusterisé ou de la création d'un index non clusterisé sur un tas. Vous verrez "Analyse d'index clusterisé" lors de la création d'un index non clusterisé sur un index clusterisé.
Cette requête ne semble pas fonctionner lors de la création d'index filtrés. Pour une raison quelconque, les index filtrés a) n'ont pas l'étape "Tri" et b) le row_count
champ n'augmente jamais à partir de 0.
Je ne sais pas ce que je testais auparavant, mais mes tests indiquent maintenant que les index filtrés sont capturés par cette requête. Doux. Mais attention, le nombre de lignes peut être désactivé (je verrai si je peux résoudre ce problème un jour).
Lors de la création d'un index cluster sur un tas qui contient déjà des index non cluster, les index non cluster doivent être reconstruits (pour échanger le RID - RowID - pour la ou les clés d'index cluster), et chaque reconstruction d'index non cluster sera être une opération distincte et donc non reflétée dans les statistiques renvoyées par cette requête lors de la création de l'index clusterisé.
Cette requête a été testée par rapport à:
- Création:
- Index non clusterisés sur un tas
- un index clusterisé (aucun index non clusterisé n'existe)
- Index non groupés sur l'index / la table groupés
- un index cluster lorsque des index non cluster existent déjà
- Index non clusterisés uniques sur l'index / la table clusterisés
- Reconstruction (table avec index cluster et un index non cluster; testé sur SQL Server 2014, 2016, 2017 et 2019) via:
ALTER TABLE [schema_name].[table_name] REBUILD;
( seul l'index clusterisé apparaît lors de l'utilisation de cette méthode )
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;
Exemple de sortie:
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
setN'Index Scan'
, plutôt queN'Table Scan'
ouN'Clustered Index Scan'
. En outre, ce sera très lent, car il effectuera un tas de recherches RID.ALTER INDEX ALL
et même (partiellement)ALTER TABLE .. REBUILD
. S'il-vous-plaît évaluez :-).