Massen-Datenimporte (bulk insert) sind eine typische Aufgabe bei Migrationen, Importen oder der Befüllung großer Tabellen. Die Effizienz dieser Operation hängt von mehreren Faktoren ab:
BULK INSERT oder COPY (PostgreSQL) - sie arbeiten schneller als gewöhnliche INSERTs in einer Schleife.BULK INSERT my_table FROM 'C:\data\bulkdata.csv' WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = ' ', BATCHSIZE = 5000, TABLOCK );
TABLOCKreduziert Konflikte bei Sperren während Massenimporte.
Frage: Kann man Indizes jederzeit deaktivieren und neu erstellen, um den Bulk Insert zu beschleunigen, wenn die Tabelle an Transaktionen beteiligt ist?
Antwort: Nein, wenn die Tabelle an aktiven Transaktionen beteiligt ist, kann das Deaktivieren oder Neuaufrufen von Indizes zu Sperren, Integritätsverlusten oder sogar Datenverlust führen, wenn die Transaktion zurückgesetzt wird. Diese Operation sollte nur außerhalb von Transaktionen durchgeführt oder Wartungsfenster im Voraus geplant werden.
-- Falsch: BEGIN TRAN; ALTER INDEX ALL ON my_table DISABLE; -- ... bulk insert ... ALTER INDEX ALL ON my_table REBUILD; COMMIT;
Solche Deaktivierungen sind innerhalb langer Transaktionen unzulässig!
Geschichte 1: In einem Projekt führten parallele Bulk Inserts in eine Tabelle mit mehreren eindeutigen Indizes zu häufigen Deadlocks und drastischen Leistungseinbrüchen. Die Lösung bestand darin, nicht-schlüsselbezogene Indizes während des Imports vorübergehend zu deaktivieren und die Batch-Größe zu reduzieren.
Geschichte 2: Entwickler vergaßen, die Überprüfung von Fremdschlüsseln während des Datenimports zu deaktivieren, wodurch jeder Insert die Existenz verwandter Datensätze in anderen großen Tabellen überprüfte. Dies erhöhte die Ladezeit auf 40 Minuten bis zu 9 Stunden. Nach der Deaktivierung der Einschränkungen dauerte die Einfügung nur 12 Minuten.
Geschichte 3: Der Versuch, eine große Datei in einer einzigen Abfrage einzufügen (ohne Batch-Verarbeitung und ohne Transaktionen), führte zu einer Überfüllung des Transaktionsprotokolls (transaction log full) und zum plötzlichen Abbruch des Datenbankservers. Nach dem Wechsel zur Batchverarbeitung verschwand das Problem.