Unser ETL-Flow verfügt über eine langjährige SELECT INTO-Anweisung, mit der eine Tabelle im laufenden Betrieb erstellt und mit mehreren hundert Millionen Datensätzen gefüllt wird.
Die Aussage sieht ungefähr so aus SELECT ... INTO DestTable FROM SrcTable
Zu Überwachungszwecken möchten wir uns einen ungefähren Überblick über den Fortschritt dieser Anweisung während der Ausführung verschaffen (ca. Zeilenanzahl, Anzahl der geschriebenen Bytes oder ähnliches).
Wir haben Folgendes erfolglos versucht:
-- 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')
Außerdem können wir die Transaktion in sehen sys.dm_tran_active_transactions
, aber ich konnte keine Möglichkeit finden, die Anzahl der betroffenen Zeilen in einer gegebenen zu ermitteln transaction_id
(etwas Ähnliches wie @@ROWCOUNT
vielleicht, aber mit dem transaction_id
Argument as).
Ich verstehe, dass auf SQL Server die SELECT INTO-Anweisung sowohl eine DDL- als auch eine DML-Anweisung in einer ist, und als solche wird die implizite Tabellenerstellung eine Sperroperation sein. Ich denke immer noch, dass es eine clevere Möglichkeit geben muss, eine Art Fortschrittsinformation zu erhalten, während die Anweisung ausgeführt wird.
Antworten:
Ich vermute, dass
rows
insys.partitions
0 ist, weil es noch nicht festgeschrieben wurde. Dies bedeutet jedoch nicht, dass SQL Server nicht weiß, was dort abläuft, wenn die Transaktion festgeschrieben wird. Der Schlüssel ist, sich daran zu erinnern, dass alle Operationen zuerst den Pufferpool (dh den Speicher) durchlaufen, unabhängig von COMMIT oder ROLLBACK der Operation. Daher können wirsys.dm_os_buffer_descriptors
nach diesen Informationen suchen :Wenn Sie die Details anzeigen möchten, kommentieren Sie die erste Zeile der Elemente in der Liste aus
SELECT
, kommentieren Sie Liste aus, und kommentieren Sie die verbleibenden 3 Zeilen aus.Ich habe getestet, indem ich das Folgende in einer Sitzung ausgeführt und dann die obige Abfrage in einer anderen wiederholt ausgeführt habe.
quelle
Einmalig oder laufend?
Wenn dies ein Bedarf ist, der im Voraus erwartet werden kann *, können Sie dies verwenden
sys.dm_exec_query_profiles
Verbindung 1 (Sitzung 55)
Anschluss 2
Sie müssen möglicherweise zurück die Zeilen zählt summieren , wenn die
SELECT INTO
ist Parallelität mit .* Die Sitzung, die Sie mit dieser DMV überwachen möchten, muss für die Statistikerfassung mit
SET STATISTICS PROFILE ON
oder aktiviert seinSET STATISTICS XML ON
. Das Anfordern eines "tatsächlichen" Ausführungsplans von SSMS funktioniert ebenfalls (da die letztere Option festgelegt ist).quelle
Ich glaube nicht, dass es eine Möglichkeit gibt, Zeilenzahlen zu ermitteln, aber Sie können die Menge der geschriebenen Daten schätzen, indem Sie Folgendes betrachten:
Wenn Sie eine Vorstellung davon haben, wie viele Seiten der Heapspeicher nach Abschluss aufnehmen soll, sollten Sie in der Lage sein,% complete zu berechnen. Die letztere Abfrage wird nicht schnell sein, wenn die Tabelle größer wird. Und wahrscheinlich am sichersten,
READ UNCOMMITTED
wenn Sie die oben genannten Optionen verwenden (und das empfehle ich nicht oft für alles).quelle
Wenn du das
INSERT
von einem ändern könntestzu einer
dann würde deine
select count(*) from DestTable with (nolock)
Abfrage funktionieren.Wenn dies nicht möglich ist, können Sie sp_WhoIsActive verwenden (oder in die DMVs eintauchen), um zu überwachen, wie viele Schreibvorgänge die Abfrage ausführt. Dies wäre eine ziemlich grobe Messgröße, könnte aber nützlich sein, wenn Sie die Anzahl der Schreibvorgänge zugrunde legen, die normalerweise ausgeführt werden.
Sie sollten in der Lage sein, minimale Protokollierung mit dem
INSERT
oben genannten zu erhalten, wenn Sie hinzufügenWITH (TABLOCK)
.quelle
INSERT
oben genannten zu erhalten, wenn Sie hinzufügenWITH(TABLOCK)
BULK_OPERATION
Sperre einnimmt .