Daher habe ich einen einfachen Masseneinfügeprozess, um Daten aus unserer Staging-Tabelle in unseren Datamart zu verschieben.
Der Vorgang ist eine einfache Datenflusstask mit den Standardeinstellungen für "Zeilen pro Stapel" und den Optionen "Tablock" und "Keine Prüfbedingung".
Der Tisch ist ziemlich groß. 587.162.986 mit einer Datengröße von 201 GB und 49 GB Indexspeicher. Der Clustered-Index für die Tabelle lautet.
CREATE CLUSTERED INDEX ImageData ON dbo.ImageData
(
DOC_ID ASC,
ACCT_NUM ASC,
MasterID ASC
)
Und der Primärschlüssel ist:
ALTER TABLE dbo.ImageData
ADD CONSTRAINT ImageData
PRIMARY KEY NONCLUSTERED
(
ImageID ASC,
DT_CRTE_DOC ASC
)
Jetzt haben wir ein Problem, bei dem BULK INSERT
über SSIS unglaublich langsam läuft. 1 Stunde, um eine Million Zeilen einzufügen. Die Abfrage, die die Tabelle auffüllt, ist bereits sortiert, und die Ausführung der Abfrage zum Auffüllen dauert weniger als eine Minute.
Wenn der Prozess ausgeführt wird, kann ich sehen, dass die Abfrage auf die BULK-Einfügung wartet, die zwischen 5 und 20 Sekunden dauert und eine Art von Wartezeit anzeigt PAGEIOLATCH_EX
. Der Prozess kann nur INSERT
ungefähr tausend Zeilen gleichzeitig verarbeiten.
Gestern, als ich diesen Prozess in meiner UAT-Umgebung getestet habe, bin ich auf dasselbe Problem gestoßen. Ich habe den Prozess einige Male ausgeführt und versucht, die Hauptursache für diese langsame Einfügung zu ermitteln. Dann fing es plötzlich an, in weniger als 5 Minuten zu rennen. Also habe ich es noch ein paar Mal ausgeführt, alle mit dem gleichen Ergebnis. Auch die Anzahl der Masseneinsätze, die 5 Sekunden oder länger gewartet haben, ging von Hunderten auf etwa 4 zurück.
Jetzt ist das verwirrend, weil es nicht so ist, als ob wir einen großen Rückgang der Aktivität hatten.
CPU während der Dauer ist niedrig.
Die Zeiten, in denen es langsamer ist, scheinen weniger Wartezeiten auf der Festplatte zu sein.
Die Festplattenlatenz erhöht sich tatsächlich während des Zeitraums, in dem der Prozess in weniger als 5 Minuten ausgeführt wurde.
Und der IO war in Zeiten, in denen dieser Prozess schlecht läuft, viel niedriger.
Ich habe es bereits überprüft und es gab kein Dateiwachstum, da die Dateien nur zu 70% voll sind. Die Protokolldatei hat noch 50% zu tun. Die Datenbank befindet sich im einfachen Wiederherstellungsmodus. DB hat nur eine Dateigruppe, verteilt sich jedoch auf 4 Dateien.
Also, was frage ich mich? A: Warum habe ich so lange auf diese Massenbeilagen gewartet? B: Welche Art von Magie hat dazu geführt, dass es schneller lief?
Randnotiz. Es läuft heute wieder scheiße.
UPDATE ist derzeit partitioniert. Es ist jedoch in einer Methode, die bestenfalls albern ist.
CREATE PARTITION SCHEME [ps_Image] AS PARTITION [pf_Image]
TO ([FG_Image], [FG_Image], [FG_Image], [FG_Image])
CREATE PARTITION FUNCTION [pf_Image](datetime) AS
RANGE RIGHT FOR VALUES (
N'2011-12-01T00:00:00.000'
, N'2013-04-01T00:00:00.000'
, N'2013-07-01T00:00:00.000'
);
Dadurch verbleiben im Wesentlichen alle Daten in der 4. Partition. Da es sich jedoch alle um die gleiche Dateigruppe handelt. Die Daten sind derzeit ziemlich gleichmäßig auf diese Dateien verteilt.
UPDATE 2 Dies sind die allgemeinen Wartezeiten, wenn der Prozess schlecht läuft.
Dies ist die Wartezeit in der Zeit, in der ich den Prozess ausführen konnte, läuft gut.
Das Speichersubsystem ist ein lokal angeschlossenes RAID, kein SAN. Die Protokolle befinden sich auf einem anderen Laufwerk. RAID-Controller ist PERC H800 mit 1 GB Cache-Größe. (Für UAT) Prod ist ein PERC (810).
Wir verwenden eine einfache Wiederherstellung ohne Backups. Es wird jede Nacht von einer Produktionskopie restauriert.
Wir haben auch IsSorted property = TRUE
in SSIS festgelegt, da die Daten bereits sortiert sind.
PAGEIOLATCH_EX
und ASYNC_IO_COMPLETION
zeigen an, dass es eine Weile dauert, bis Daten von der Festplatte in den Speicher gelangen. Dies kann ein Hinweis auf ein Problem mit dem Festplattensubsystem sein oder ein Speicherkonflikt. Wie viel Speicher hat SQL Server zur Verfügung?
ASYNC_NETWORK_IO
Bedeutet, dass SQL Server darauf gewartet hat , Zeilen an einen Client zu senden . Ich nehme an, das zeigt die Aktivität von SSIS, die Zeilen aus der Staging-Tabelle verbraucht.