web-dev-qa-db-fra.com

SQL Server: comment suivre la progression de la commande CREATE INDEX?

SQL Server 2014, Std Ed

J'ai lu que percent_complete dans dm_exec_requests ne fonctionne pas pour CREATE INDEX, et dans la pratique, percent_complete reste à 0. Donc ça n'aide pas.

J'utilise actuellement la méthode ci-dessous, qui au moins me montre le mouvement (que la création d'index n'est pas bloquée). Mais je n'ai aucune idée si je suis% 10 à travers le processus ou% 99.

J'ai essayé la méthode décrite ici: https://dba.stackexchange.com/a/102545/6229 mais elle montre un temps d'achèvement est clairement erroné (elle montre essentiellement 'maintenant' pendant plus de 60 minutes processus dans lequel je suis 10 min)

Comment puis-je obtenir un indice?

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

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 Answer: Progression de SELECT Déclaration 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 effectue le CREATE INDEX (et placé avant le CREATE INDEX, si ce n'était pas évident), sinon aucune ligne n'apparaîtra dans ce DMV pour ce SPID/session_id !!

  • L'opérateur IN est utilisé pour filtrer le Index Insert ligne qui, si elle est incluse, augmentera les valeurs TotalRows, ce qui faussera les calculs puisque cette ligne n'affiche jamais aucune ligne traitée.

  • Le nombre de lignes affiché ici (c'est-à-dire 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 un "Tableau Scan" ou "Clustered Index Scan ", et le deuxième est le" Tri ". 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 le champ n'augmente jamais de 0.
    Je ne sais pas ce que je testais auparavant, mais mes tests indiquent maintenant que les index filtrés le 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 (tableau avec index clusterisé et un index non clusterisé; 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
69
Solomon Rutzky

Étant donné que cette rubrique semble toujours active, j'ai pensé qu'il serait utile de noter que l'utilisation des nouvelles opérations d'indexation de reprise dans SQL Server 2019 et Azure SQL DB (en mode de compatibilité 150) fournit cette fonctionnalité. La vue du catalogue sys.index_resumable_operations a une colonne percent_complete qui indique la progression.

En plus de pouvoir surveiller la création et la reconstruction d'index, les opérations d'indexation pouvant être reprises aident également en divisant l'opération en petits morceaux qui sont validés à mesure que l'opération progresse. Cela aide à garder le journal des transactions petit et peut également aider avec des choses comme les groupes de disponibilité car l'opération peut être répliquée sur n'importe quel serveur secondaire. Avec les opérations d'indexation pouvant être reprises, vous pouvez reprendre la création ou la reconstruction de l'index sur le nouveau serveur principal après un basculement sans perte de progression, et puisque les transactions sont validées en cours de route, vous n'aurez pas le problème de la synchronisation de la sauvegarde pendant les opérations d'indexation longues .

2
Pam Lahoud