Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment puis-je capturer les données transmises dans SqlBulkCopy à l'aide du Sql Profiler ?

Capture des informations d'événement pour les opérations d'insertion en masse ( BCP.EXE , SqlBulkCopy , et je suppose que BULK INSERT , et OPENROWSET(BULK... ) est possible, mais vous ne pourrez pas voir les lignes et les colonnes individuelles.

Les opérations d'insertion en bloc s'affichent sous la forme d'une instruction DML unique (enfin, une par lot, et la valeur par défaut est de faire toutes les lignes dans un seul lot) :

INSERT BULK <destination_table_name> (
      <column1_name> <column1_datatype> [ COLLATE <column1_collation> ], ...
      ) [ WITH (<1 or more hints>) ]

<hints> := KEEP_NULLS, TABLOCK, ORDER(...), ROWS_PER_BATCH=, etc

Vous pouvez trouver la liste complète des "conseils" sur la page MSDN pour le BCP Utilitaire . Veuillez noter que SqlBulkCopy ne prend en charge qu'un sous-ensemble de ces indices (par exemple, KEEP_NULLS , TABLOCK , et quelques autres) mais pas prend en charge ORDER(...) ou ROWS_PER_BATCH= (ce qui est assez dommage, en fait, car le ORDER() indice est nécessaire pour éviter un tri qui se produit dans tempdb afin de permettre à l'opération d'être journalisée de manière minimale (en supposant que les autres conditions pour une telle opération ont également été satisfaites).

Pour voir cette déclaration, vous devez capturer l'un des événements suivants dans SQL Server Profiler :

Vous voudrez également sélectionner, au moins, les colonnes suivantes (dans SQL Server Profiler) :

Et, puisqu'un utilisateur ne peut pas soumettre un INSERT BULK déclaration directement, vous pouvez probablement filtrer cela dans les filtres de colonne si vous voulez simplement voir ces événements et rien d'autre.

Si vous souhaitez voir la notification officielle qu'un BULK INSERT l'opération commence et/ou se termine, vous devez capturer l'événement suivant :

puis ajoutez les colonnes Profiler suivantes :

Pour ObjectName vous obtiendrez toujours des événements affichant "BULK INSERT" et si cela commence ou se termine est déterminé par la valeur dans EventSubClass , qui est soit "0 - Begin" ou "1 - Commit" (et je suppose que si cela échoue, vous devriez voir "2 - Rollback").

Si la ORDER() l'indice n'a pas été spécifié (et encore une fois, il ne peut pas être spécifié lors de l'utilisation de SqlBulkCopy ), alors vous obtiendrez également un événement "SQLTransaction" affichant "sort_init" dans le ObjectName colonne. Cet événement a également des événements "0 - Begin" et "1 - Commit" (comme indiqué dans le EventSubClass colonne).

Enfin, même si vous ne pouvez pas voir les lignes spécifiques, vous pouvez toujours voir les opérations par rapport au journal des transactions (par exemple, insérer une ligne, modifier une ligne IAM, modifier une ligne PFS, etc.) si vous capturez l'événement suivant :

et ajoutez la colonne Profiler suivante :

Les principales informations d'intérêt seront dans le EventSubClass colonne, mais malheureusement, ce ne sont que des valeurs d'ID et je n'ai trouvé aucune traduction de ces valeurs dans la documentation MSDN. Cependant, j'ai trouvé le billet de blog suivant de Jonathan Kehayias :Utilisation d'événements étendus dans SQL Server Denali CTP1 pour mapper l'événement TransactionLog SQL Trace Valeurs EventSubClass .

@RBarryYoung a souligné que les valeurs et les noms EventSubClass peuvent être trouvés dans le sys.trace_subclass_values vue du catalogue, mais l'interrogation de cette vue montre qu'elle n'a pas de lignes pour le TransactionLog événement :

SELECT * FROM sys.trace_categories -- 12 = Transactions
SELECT * FROM sys.trace_events WHERE category_id = 12 -- 54 = TransactionLog
SELECT * FROM sys.trace_subclass_values WHERE trace_event_id = 54 -- nothing :(

Veuillez noter que le SqlBulkCopy.BatchSize propriété équivaut à définir le -b option pour BCP.EXE , qui est un paramètre opérationnel qui contrôle la façon dont chaque commande divisera les lignes en ensembles. Ce n'est pas la même chose que le ROWS_PER_BATCH= indice qui ne contrôle pas physiquement la façon dont les lignes sont divisées en ensembles, mais permet à la place à SQL Server de mieux planifier la façon dont il allouera les pages, et donc réduit le nombre d'entrées dans le journal des transactions (parfois d'un peu). Pourtant, mes tests ont montré que :

  • en spécifiant -b pour BCP.EXE a défini le ROWS_PER_BATCH= allusion à cette même valeur.
  • spécifier le SqlBulkCopy.BatchSize la propriété n'a pas définir le ROWS_PER_BATCH= indice, MAIS, l'avantage de la réduction de l'activité du journal des transactions était en quelque sorte définitivement là (magique?). Le fait que l'effet net est de toujours gagner l'avantage est la raison pour laquelle je ne l'ai pas mentionné vers le haut quand j'ai dit qu'il était regrettable que le ORDER() l'indice n'était pas pris en charge par SqlBulkCopy .