Nasz przepływ ETL ma długo działającą instrukcję SELECT INTO, która tworzy tabelę w locie i zapełnia ją setkami milionów rekordów.
Oświadczenie wygląda mniej więcej tak SELECT ... INTO DestTable FROM SrcTable
Do celów monitorowania chcielibyśmy uzyskać ogólne pojęcie o postępie wykonywania tej instrukcji podczas jej wykonywania (przybliżona liczba wierszy, liczba zapisanych bajtów lub podobna).
Wypróbowaliśmy następujące bezskutecznie:
-- Is blocked by the SELECT INTO statement:
select count(*) from DestTable with (nolock)
-- Returns 0, 0:
select rows, rowmodctr
from sysindexes with (nolock)
where id = object_id('DestTable')
-- Returns 0:
select rows
from sys.partitions
where object_id = object_id('DestTable')
Co więcej, widzimy transakcję sys.dm_tran_active_transactions
, ale nie byłem w stanie znaleźć sposobu, aby uzyskać liczbę dotkniętych wierszy w danym transaction_id
(może coś podobnego do @@ROWCOUNT
, ale z transaction_id
argumentem as).
Rozumiem, że na SQL Server instrukcja SELECT INTO jest zarówno instrukcją DDL, jak i DML w jednym, i jako takie, niejawne tworzenie tabeli będzie operacją blokującą. Nadal uważam, że musi istnieć jakiś sprytny sposób na uzyskanie pewnego rodzaju informacji o postępie podczas działania instrukcji.
Odpowiedzi:
Podejrzewam, że
rows
insys.partitions
ma wartość 0, ponieważ nie zostało jeszcze popełnione. Ale to nie znaczy, że SQL Server nie wie, co się tam stanie, jeśli transakcja się zatwierdzi. Kluczem jest zapamiętywanie, że wszystkie operacje najpierw przechodzą przez pulę buforów (tj. Pamięć), bez względu na COMMIT lub ROLLBACK operacji. Dlatego możemy poszukaćsys.dm_os_buffer_descriptors
tych informacji:Jeśli chcesz zobaczyć szczegóły, usuń komentarz z pierwszego wiersza pozycji na
SELECT
liście, skomentuj pozostałe 3 wiersze.Testowałem, uruchamiając poniższe w jednej sesji, a następnie wielokrotnie uruchamiając powyższe zapytanie w innej.
źródło
Jednorazowy czy trwa?
Jeśli jest to potrzeba, którą można przewidzieć z wyprzedzeniem *, możesz skorzystać
sys.dm_exec_query_profiles
Połączenie 1 (sesja 55)
Połączenie 2
Być może trzeba zsumować liczbę zwracanych wierszy, jeżeli
SELECT INTO
jest za pomocą równoległości .* Sesja, którą chcesz monitorować za pomocą tego DMV, musi być włączona do zbierania statystyk za pomocą
SET STATISTICS PROFILE ON
lubSET STATISTICS XML ON
. Żądanie „rzeczywistego” planu wykonania z SSMS również działa (ponieważ ustawia tę drugą opcję).źródło
Nie sądzę, że istnieje sposób na uzyskanie liczby wierszy, ale można oszacować ilość danych zapisanych na podstawie:
Jeśli masz jakieś pojęcie o tym, ile stron sterty powinno zająć po zakończeniu, powinieneś być w stanie wypracować% ukończenia. To ostatnie zapytanie nie będzie szybkie, gdy tabela się powiększy. I prawdopodobnie najbezpieczniej jest uruchomić powyższe pod
READ UNCOMMITTED
(i nie zawsze tak polecam, na cokolwiek).źródło
Jeśli możesz zmienić
INSERT
zdo
wtedy twoje
select count(*) from DestTable with (nolock)
zapytanie zadziałałoby.Jeśli nie jest to możliwe, możesz użyć sp_WhoIsActive (lub zagłębić się w DMV) do monitorowania liczby zapisów zapytania. Byłby to dość szorstki miernik, ale może być użyteczny, jeśli podstawa wyrówna liczbę zapisów, co zwykle.
Jeśli dodasz, powinieneś być w stanie uzyskać minimalne logowanie przy użyciu
INSERT
powyższegoWITH (TABLOCK)
.źródło
INSERT
powyższego, jeśli dodaszWITH(TABLOCK)
BULK_OPERATION
blokady.