2017-03-28 7 views
0

Ich habe eine DataTable mit ca. 500K + Datensätze, und ich möchte ein Feld in der Datenbank für jeden dieser Datensätze in der DataTable aktualisieren.Viele Zeilen aktualisieren

Im Moment bekomme ich eine Liste aller Datensätze in der ID-Spalte der Datentabelle und eine Update-Anweisung mit einer SQL-in Anweisung Erstellen auf diesem IDs, etwa so:

string sql = "UPDATE my_table SET my_field = @timestamp WHERE id IN (" + String.Join(", ", myDataTable.AsEnumerable().Select(r => r.Field<Int64>("id")).ToList().ToArray()) + ")"; 

Dies funktioniert Bei einigen Datensätzen bekomme ich jedoch aufgrund der großen Anzahl von IDs einen Fehler, der besagt, dass die Paketgröße in MySQL für diese Abfrage nicht groß genug ist.

Was kann neben der Erhöhung der Paketgröße getan werden, was ein schlechter Ansatz zu sein scheint?

+0

Wie Sie dann von IN-Klausel Ergebnis erhalten ..? ist möglich, das gleiche Ergebnis mit einer Abfrage zu erhalten? – scaisEdge

+0

Ich würde damit beginnen, Ihre Abfrage nicht auf diese Weise aufzubauen. Da Sie dieses C# getaggt haben, würde ich annehmen, dass Sie Zugriff auf ADO.NET haben, was bedeutet, dass Sie Ihre Abfrage parametrisieren können. –

+0

Ich zweite Tonson T. Kommentar.Möchten Sie alle Datensätze in dieser Tabelle aktualisieren? Ist die Liste der IDs in einer anderen Tabelle zu aktualisieren? Wenn dies der Fall ist, verwenden Sie eine Verknüpfung, um auszuwählen, welche Datensätze aktualisiert werden sollen. –

Antwort

0

Ich weiß nicht, ob es möglich ist, die Paketgröße in MySQL zu erhöhen, aber es gibt eine einfache Lösung für Ihr Problem, indem Sie Ihre UPDATE-Abfrage an mehr UPDATE Abfragen für mehrere Gruppen von IDs

+0

Gibt es einen sauberen Weg, dies zu tun? Anders als explizit für eine bestimmte Anzahl von Wiederholungen zu iterieren? – Horace

+0

mmmmm Ich glaube nicht, dass es einen anderen Weg gibt, aber Sie sollten versuchen, die maximale Anzahl von IDs zu überprüfen, bei denen Ihre Abfrage übergeben wird, und dann teilen Sie Ihre IDs in Gruppen basierend auf dieser Nummer. –

0

Unter der Annahme, Dividieren id_list_table eine Liste von IDs enthält in my_table zu aktualisieren: einmal

UPDATE my_table 
SET my_field = @timestamp 
JOIN id_list_table 
ON my_table.id = id_list_table.my_table_id 
+0

Es ist eher eine Datentabelle als eine Datenbanktabelle – Horace

+0

Dann würde ich einen Ansatz vorschlagen, wie Abdullah Dibas erwähnt. Verwenden Sie eine kleinere Anzahl von Datensatz-IDs und mehrere Update-Anweisungen. Wiederholen Sie einfach die X-Nummer der IDs pro Schleife, bis Sie die gesamte Liste durchlesen. –

0

Für ähnliche Aufgabe habe ich den folgenden Ansatz:

  1. zusätzliche Tabelle erstellen mit Spalten session_id GUID, record_id bigint.
  2. Bevor Sie den Aktualisierungsvorgang starten, generieren Sie einen eindeutigen Bezeichner für diese Operation (session_id).
  3. Fügen Sie alle IDs, die Sie aktualisieren müssen, zusammen mit der generierten Sitzungs-ID in diese Tabelle ein.
  4. UPDATE primäre Tabelle mit INNER JOIN zu dieser Tabelle, die bestimmte Session-ID angibt.
  5. DELETE Alle Datensätze aus der Sitzungstabelle nach Sitzungs-ID.

Wenn es fertig ist können Sie mit der Arbeit auf die Leistung starten:

  • Protokollierung für die Sitzungstabelle ausschalten, da es keine wesentlichen Daten enthält;
  • experimentieren mit der Erstellung von Temp-Tabelle jedes Mal, wenn Sie es brauchen statt statische (in der Theorie würde es Reinigung vereinfachen, da DROP TABLE viel schneller als DELETE FROM arbeiten muss, aber in meinem Fall Erstellung Tisch zu langsam arbeitete ich lieber permanent Tabelle);
  • Verwenden Sie bigint anstelle von GUID -s zum Identifizieren von Sitzungen, da sie schneller verglichen werden müssen;
  • Verwenden Sie COPY FROM (PostgreSQL) oder BULK INSERT (MS SQL) -Anweisung anstelle der Serie von INSERT INTO -s. Ich habe jedoch nichts Ähnliches für MySQL gefunden.

Ich weiß nicht, was Ihnen am besten passen wird)

Verwandte Themen