Entwickler-Ecke
Datenbanken (inkl. ADO.NET) - SQL XML-Datenimport Performance
mats74 - Mi 21.11.12 11:56
Titel: SQL XML-Datenimport Performance
Hallo zusammen
Meine Aufgabe:
- Daten aus bestehenden XML-Dateien in bestehende Datensätze in SQL-Tabellen übernehmen
- Die Tabellen haben Foreign-Key Schlüssel, dadurch können die ID's der zu ersetzenden Datensätze nicht geändert werden
(also keine DELETE und INSERT-Anweisung möglich)
Folgender Code funktioniert, wird aber nach ca. 1000 eingetragenen Datensätzen extrem, massiv und unerträglich langsam :P :
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| foreach (XmlNode _xmlnode in _xmlnodelist1) { for (int ii = 0; ii < ia_temp_wert.Length; ii++) { if (Convert.ToInt32(_xmldocument.GetElementsByTagName("IRGENDETWAS").Item(i).InnerText) == ii) { befehl.CommandText = "UPDATE MEINETABELLE SET " + "MEINESPALTE = '" + Convert.ToString(_xmldocument.GetElementsByTagName("IRGENDETWAS").Item(i).InnerText) + "'," + "WHERE MEINEID = " + Convert.ToInt32(_xmldocument.GetElementsByTagName("ANDEREID").Item(i).InnerText) + ";"; befehl.ExecuteNonQuery(); break; } else { } }
i++; } |
Den Zeitverlust vermute ich im Query, das wahrscheinlich bei jedem Dateneintrag neu geparst wird.
Habe aber keine Ahnung, wie ich dies zu vermeiden habe.
Wie kann ich die Performance meines Imports erhöhen (damit meine Wenigkeit nicht in Dauerschlaf verfällt :wink: )?
Welche Importmöglichkeiten sind sonst noch zu prüfen?
Ich habe noch weiter Tabellen zu updaten, die mehr als 50000 Datensätze beinhalten, somit eine Wartezeit von über 10 h bewirken.
Muss definitiv auch schneller zu erstellen sein.
Danke für eure Hilfe.
Ralf Jansen - Mi 21.11.12 13:04
Zitat: |
Den Zeitverlust vermute ich im Query, das wahrscheinlich bei jedem Dateneintrag neu geparst wird. |
Eher nicht. Der SQL Server(oder vergleichbare andere Datenbanken) ist eigentlich schlau genug zu erkennen das er dieses Abfragemuster kurz vorher schon mal hatte und wird denn Ausführungsplan wiederverwenden. Davon abgesehen sollte der Ausführungsplan bei einem simplen update auch ziemlich simpel sein und nicht wirklich Zeitkosten den zu ermitteln. Um sicherzugehen das das passiert und weil es eh Best Practice ist benutze
Parameter [
http://openbook.galileocomputing.de/visual_csharp_2010/visual_csharp_2010_24_004.htm#mjcb7167c9d0e658cb195c9840f73556d7] für deinen Command und keine Stringzusammenwürfelei. Dann wird der Ausführungsplan garantiert wiederverwendet.
Was da langsam ist - die Query, die 1000 Ping Pong zwischen Programm und DB, die Authentifizierung bei jedem Aufruf etc. - solltest du mit entsprechenden Tools überprüfen. Also den Profiler vom SQL Server(bzw. die Entsprechung für dein Datenbankmodel) oder dem PerformanceMonitor von Windows.
mats74 - Mi 21.11.12 16:16
Hallo Ralf
Vielen Dank für den Tip der parametrisierung der SQL-Statements.
Daran habe ich nicht mehr gedacht.
Das hat eine starke Verbesserung der Performance gegenüber einer Zuweisung eines (gebastelten :wink: ) Strings gebracht.
Der Ausführungsplan wurde wiederverwendet.
Die eigentliche Bremse war die For-Schleife.
Die habe ich dadurch eliminiert, dass ich die betreffenden Tabellen vorgängig entsprechend ergänzt und verändert habe.
Der erfolgreiche Code sieht nun folgendermassen aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| string text = "UPDATE MEINETABELLE SET " + "MEINESPALTE = @anderespalte," + "WHERE MEINEID = @andere_id;";
foreach (XmlNode _xmlnode in _xmlnodelist1) { befehl = new SqlCommand(text, verbindung); befehl.Parameters.AddWithValue("@anderespalte", Convert.ToString(_xmldocument.GetElementsByTagName("ANDERESPALTE").Item(i).InnerText)); befehl.Parameters.AddWithValue("@andere_id", Convert.ToString(_xmldocument.GetElementsByTagName("ANDEREID").Item(i).InnerText)); befehl.ExecuteNonQuery();
i++; } |
Mit dieser Struktur beträgt die Einfügezeit pro Zeile ca. 1/100s pro Datensatz.
Somit auch bei grossen Tabellen Aufgabe gelöst.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!