sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cómo capturo los datos pasados ​​en SqlBulkCopy usando Sql Profiler?

Captura de información de eventos para operaciones de inserción masiva ( BCP.EXE , SqlBulkCopy , y asumo BULK INSERT y OPENROWSET(BULK... ) es posible, pero no podrá ver las filas y columnas individuales.

Las operaciones de inserción masiva se muestran como una declaración DML única (bueno, una por lote, y el valor predeterminado es hacer todas las filas en un solo lote):

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

Puede encontrar la lista completa de "sugerencias" en la página de MSDN para el BCP Utilidad . Tenga en cuenta que SqlBulkCopy solo admite un subconjunto de esas sugerencias (por ejemplo, KEEP_NULLS , TABLOCK , y algunos otros) pero no soporte ORDER(...) o ROWS_PER_BATCH= (lo cual es bastante desafortunado, en realidad, ya que ORDER() se necesita una sugerencia para evitar una clasificación que ocurre en tempdb para permitir que la operación se registre mínimamente (suponiendo que también se hayan cumplido las otras condiciones para tal operación).

Para ver esta declaración, debe capturar cualquiera de los siguientes eventos en SQL Server Profiler:

También querrá seleccionar, al menos, las siguientes columnas (en SQL Server Profiler):

Y, dado que un usuario no puede enviar un INSERT BULK declaración directamente, probablemente pueda filtrar eso en Filtros de columna si simplemente desea ver estos eventos y nada más.

Si desea ver la notificación oficial de que un BULK INSERT la operación está comenzando y/o finalizando, entonces necesita capturar el siguiente evento:

y luego agregue las siguientes columnas de Profiler:

Para ObjectName siempre obtendrá eventos que muestran "BULK INSERT" y si eso comienza o finaliza está determinado por el valor en EventSubClass , que es "0 - Comenzar" o "1 - Confirmar" (y supongo que si falla deberías ver "2 - Retroceder").

Si el ORDER() no se especificó la sugerencia (y de nuevo, no puede especificarse al usar SqlBulkCopy ), también obtendrá un evento "SQLTransaction" que muestra "sort_init" en ObjectName columna. Este evento también tiene eventos "0 - Comenzar" y "1 - Confirmar" (como se muestra en EventSubClass columna).

Finalmente, aunque no puede ver las filas específicas, aún puede ver las operaciones en el registro de transacciones (por ejemplo, insertar fila, modificar fila de IAM, modificar fila de PFS, etc.) si captura el siguiente evento:

y agregue la siguiente columna de Profiler:

La información principal de interés estará en EventSubClass columna, pero desafortunadamente son solo valores de ID y no pude encontrar ninguna traducción de esos valores en la documentación de MSDN. Sin embargo, encontré la siguiente publicación de blog de Jonathan Kehayias:Uso de eventos extendidos en SQL Server Denali CTP1 para mapear el evento de seguimiento de TransactionLog SQL Valores de EventSubClass .

@RBarryYoung señaló que los valores y nombres de EventSubClass se pueden encontrar en sys.trace_subclass_values vista de catálogo, pero consultar esa vista muestra que no tiene filas para el TransactionLog evento:

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 :(

Tenga en cuenta que SqlBulkCopy.BatchSize propiedad es equivalente a establecer -b opción para BCP.EXE , que es una configuración operativa que controla cómo cada comando dividirá las filas en conjuntos. Esto no es lo mismo que el ROWS_PER_BATCH= sugerencia que no controla físicamente cómo se dividen las filas en conjuntos, sino que permite a SQL Server planificar mejor cómo asignará las páginas y, por lo tanto, reduce la cantidad de entradas en el Registro de transacciones (a veces bastante). Aún así, mis pruebas mostraron que:

  • especificando -b para BCP.EXE estableció el ROWS_PER_BATCH= insinúe ese mismo valor.
  • especificando el SqlBulkCopy.BatchSize la propiedad no establecer el ROWS_PER_BATCH= pista, PERO, el beneficio de la actividad reducida del registro de transacciones definitivamente estaba ahí (¿magia?). El hecho de que el efecto neto sea seguir obteniendo el beneficio es la razón por la que no lo mencioné en la parte superior cuando dije que era desafortunado que ORDER() sugerencia no fue compatible con SqlBulkCopy .