sql >> Database >  >> RDS >> Sqlserver

Hoe leg ik de gegevens vast die zijn doorgegeven in SqlBulkCopy met behulp van de Sql Profiler?

Gebeurtenisinformatie vastleggen voor bulkinvoegbewerkingen ( BCP.EXE , SqlBulkCopy , en ik neem aan dat BULK INSERT , en OPENROWSET(BULK... ) is mogelijk, maar u kunt de afzonderlijke rijen en kolommen niet zien.

Bulk-invoegbewerkingen worden weergegeven als een enkele (nou ja, één per batch, en de standaard is om alle rijen in een enkele batch te doen) DML-instructie van:

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

U kunt de volledige lijst met "hints" vinden op de MSDN-pagina voor de BCP Hulpprogramma . Houd er rekening mee dat SqlBulkCopy alleen een subset van die hints ondersteunt (bijv. KEEP_NULLS , TABLOCK , en een paar anderen) maar doet niet ondersteuning ORDER(...) of ROWS_PER_BATCH= (wat eigenlijk best jammer is, aangezien de ORDER() hint is nodig om een ​​sortering in tempdb te voorkomen, zodat de bewerking minimaal kan worden geregistreerd (ervan uitgaande dat ook aan de andere voorwaarden voor een dergelijke bewerking is voldaan).

Om deze instructie te zien, moet u een van de volgende gebeurtenissen vastleggen in SQL Server Profiler:

U wilt ook ten minste de volgende kolommen selecteren (in SQL Server Profiler):

En aangezien een gebruiker geen INSERT BULK kan indienen, statement direct, kunt u daar waarschijnlijk op filteren in Kolomfilters als u alleen deze gebeurtenissen wilt zien en niets anders.

Als u de officiële melding wilt zien dat een BULK INSERT bewerking begint en/of eindigt, moet u de volgende gebeurtenis vastleggen:

en voeg vervolgens de volgende Profiler-kolommen toe:

Voor ObjectName u krijgt altijd gebeurtenissen met "BULK INSERT" en of dat begin of einde is, wordt bepaald door de waarde in EventSubClass , wat ofwel "0 - Begin" of "1 - Commit" is (en ik veronderstel dat als het mislukt, u "2 - Rollback" zou moeten zien).

Als de ORDER() hint is niet opgegeven (en nogmaals, het kan niet worden opgegeven bij gebruik van SqlBulkCopy ), dan krijgt u ook een "SQLTransaction" -gebeurtenis met "sort_init" in de ObjectName kolom. Deze gebeurtenis heeft ook "0 - Begin" en "1 - Commit" -gebeurtenissen (zoals weergegeven in de EventSubClass kolom).

Ten slotte, hoewel u de specifieke rijen niet kunt zien, kunt u nog steeds bewerkingen zien in het transactielogboek (bijv. rij invoegen, IAM-rij wijzigen, PFS-rij wijzigen, enz.) als u de volgende gebeurtenis vastlegt:

en voeg de volgende Profiler-kolom toe:

De belangrijkste informatie staat in de EventSubClass kolom, maar helaas zijn het alleen ID-waarden en ik kon geen vertaling van die waarden vinden in de MSDN-documentatie. Ik vond echter de volgende blogpost van Jonathan Kehayias:Uitgebreide gebeurtenissen gebruiken in SQL Server Denali CTP1 om de TransactionLog SQL Trace-gebeurtenis in kaart te brengen EventSubClass-waarden .

@RBarryYoung wees erop dat EventSubClass-waarden en -namen te vinden zijn in de sys.trace_subclass_values catalogusweergave, maar als u die weergave opvraagt, blijkt dat deze geen rijen heeft voor de TransactionLog evenement:

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

Houd er rekening mee dat de SqlBulkCopy.BatchSize eigenschap is gelijk aan het instellen van de -b optie voor BCP.EXE , wat een operationele instelling is die bepaalt hoe elke opdracht de rijen in sets opdeelt. Dit is niet hetzelfde als de ROWS_PER_BATCH= hint die niet fysiek bepaalt hoe de rijen in sets worden opgedeeld, maar in plaats daarvan SQL Server in staat stelt beter te plannen hoe het pagina's zal toewijzen, en dus het aantal vermeldingen in het transactielogboek vermindert (soms behoorlijk). Toch toonden mijn testen aan dat:

  • het specificeren van -b voor BCP.EXE heeft de ROWS_PER_BATCH= . ingesteld hint naar diezelfde waarde.
  • het specificeren van de SqlBulkCopy.BatchSize eigenschap deed niet stel de ROWS_PER_BATCH= . in hint, MAAR, het voordeel van verminderde transactielogboekactiviteit was op de een of andere manier zeker aanwezig (magie?). Het feit dat het netto-effect is om nog steeds het voordeel te behalen, is de reden waarom ik het niet bovenaan vermeldde toen ik zei dat het jammer was dat de ORDER() hint werd niet ondersteund door SqlBulkCopy .


  1. Hoe MySQL 5.7 volledig van Windows te verwijderen

  2. distinct() functie (geen kwalificatie selecteren) in postgres

  3. Oracle's OUTER JOIN (+) op string - Migratie PostgreSQL

  4. Voer mysql create function statement uit met PHP