Przechwytywanie informacji o zdarzeniach dla zbiorczych operacji wstawiania ( BCP.EXE
, SqlBulkCopy
, i zakładam, że BULK INSERT
i OPENROWSET(BULK...
) jest możliwe, ale nie będzie można zobaczyć poszczególnych wierszy i kolumn.
Operacje wstawiania zbiorczego są wyświetlane jako pojedyncza (no cóż, jedna na partię, a domyślnie wszystkie wiersze w jednej partii) oświadczenie DML:
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
Pełną listę „wskazówek” można znaleźć na stronie MSDN dla BCP Narzędzie
. Należy pamiętać, że SqlBulkCopy obsługuje tylko podzbiór tych wskazówek (np. KEEP_NULLS
, TABLOCK
i kilka innych), ale nie obsługa ORDER(...)
lub ROWS_PER_BATCH=
(co jest dość niefortunne, ponieważ ORDER()
wskazówka jest potrzebna, aby uniknąć sortowania, które ma miejsce w tempdb, aby umożliwić minimalne rejestrowanie operacji (zakładając, że inne warunki dla takiej operacji również zostały spełnione).
Aby zobaczyć tę instrukcję, musisz przechwycić dowolne z następujących zdarzeń w programie SQL Server Profiler:
Będziesz także chciał wybrać przynajmniej następujące kolumny (w SQL Server Profiler):
A ponieważ użytkownik nie może przesłać INSERT BULK
oświadczenie bezpośrednio, prawdopodobnie możesz filtrować według tego w Filtrach kolumn, jeśli chcesz tylko zobaczyć te zdarzenia i nic więcej.
Jeśli chcesz zobaczyć oficjalne powiadomienie, że BULK INSERT
operacja zaczyna się i/lub kończy, musisz uchwycić następujące zdarzenie:
a następnie dodaj następujące kolumny Profiler:
Dla ObjectName
zawsze otrzymasz zdarzenia pokazujące "WSTAW ZBIORCZY", a to, czy jest to początek, czy koniec zależy od wartości w EventSubClass
, czyli „0 – Początek” lub „1 – Zatwierdź” (przypuszczam, że jeśli się nie powiedzie, zobaczysz „2 – Cofnij”).
Jeśli ORDER()
wskazówka nie została określona (i ponownie, nie może być określone podczas używania SqlBulkCopy
), otrzymasz również zdarzenie "SQLTransaction" pokazujące "sort_init" w ObjectName
kolumna. To zdarzenie ma również zdarzenia „0 — Początek” i „1 — Zatwierdź” (jak pokazano w EventSubClass
kolumna).
Wreszcie, nawet jeśli nie widzisz określonych wierszy, nadal możesz zobaczyć operacje w dzienniku transakcji (np. wstaw wiersz, zmodyfikuj wiersz uprawnień, zmodyfikuj wiersz PFS itp.), jeśli przechwycisz następujące zdarzenie:
i dodaj następującą kolumnę Profiler:
Główne informacje, które Cię interesują, będą znajdować się w EventSubClass
kolumna, ale niestety to tylko wartości ID i nie mogłem znaleźć żadnego tłumaczenia tych wartości w dokumentacji MSDN. Jednak znalazłem następujący wpis na blogu autorstwa Jonathana Kehayiasa:Korzystanie z rozszerzonych zdarzeń w SQL Server Denali CTP1 do mapowania zdarzenia śledzenia SQL TransactionLog Wartości EventSubClass
.
@RBarryYoung wskazał, że wartości i nazwy EventSubClass można znaleźć w sys.trace_subclass_values
widoku katalogu, ale zapytanie tego widoku pokazuje, że nie ma wierszy dla TransactionLog
wydarzenie:
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 :(
Należy pamiętać, że SqlBulkCopy.BatchSize
właściwość jest równoważna ustawieniu -b
opcja dla BCP.EXE , czyli ustawienie operacyjne, które kontroluje sposób, w jaki każde polecenie podzieli wiersze na zestawy. To nie to samo co ROWS_PER_BATCH=
wskazówka, która nie kontroluje fizycznie sposobu podziału wierszy na zestawy, ale zamiast tego pozwala SQL Serverowi lepiej zaplanować sposób przydzielania stron, a tym samym zmniejsza liczbę wpisów w Dzienniku transakcji (czasami całkiem). Jednak moje testy wykazały, że:
- określenie
-b
dla BCP.EXE ustawiłROWS_PER_BATCH=
wskazówka do tej samej wartości. - określenie
SqlBulkCopy.BatchSize
własność nie ustawROWS_PER_BATCH=
wskazówka, ALE, korzyść ze zmniejszonej aktywności dziennika transakcji była w jakiś sposób zdecydowanie tam (magia?). Fakt, że efektem netto jest nadal uzyskanie korzyści, dlatego nie wspomniałem o tym na górze, gdy powiedziałem, że to niefortunne, żeORDER()
wskazówka nie była obsługiwana przezSqlBulkCopy
.