füllen Sie schnell einen MySQL mit einer großen Reihe von Zeilen

8

Ich habe eine MySQL-Tabelle, die so aussieht:

Die SQL zum Erstellen der Struktur lautet:

%Vor%

Es speichert eine eindeutige id , responseCode und lastUpdate . % Co_de% ist ein HTTP-Anfrage-Antwortcode: 404, 500, 503, 200, usw.

Ich habe eine URL, die jeder responseCode entspricht, für die ich eine HTTP-Anfrage mache, und notiere in dieser Tabelle die Zeit, zu der ich die Anfrage und die Antwort erhalten habe.

Das Skript erstellt diese Abfrage für die Tabelle id :

%Vor%

Wo status ein Datum wäre, an dem ich entscheide, dass alles, was älter ist als dieses Datum, unabhängig vom Antwortcode aktualisiert werden muss. Außerdem möchte ich die HTTP-Anfrage erneut versuchen, wenn ich keine XXXX oder 200 unabhängig vom letzten 404 Datum erhalten habe. I lastUpdate zu 100, weil ich nur 100 auf einmal laufen lasse, und dann habe ich es für eine Weile schlafen und noch 100 später, und so weiter.

Wie auch immer, alles in Ordnung, aber was ich tun möchte, ist, den Tisch im Voraus mit einer solchen Serie zu füllen:

%Vor%

Beachten Sie, dass nur die ID inkrementiert, aber es muss nicht unbedingt bei 1 für meine Bedürfnisse beginnen. Ich möchte, dass die Tabelle so vorbelegt wird, denn dann kann die obige Abfrage weiterhin LIMIT für diejenigen enthalten, die wir erneut versuchen müssen, und ich möchte niemals mehr in die Tabelle id als einfügen Die status sind endlich und werden sich nicht ändern (aber es gibt viele von ihnen).

Ich habe versucht, JAVA zu verwenden (obwohl PHP, C # oder was auch immer das gleiche Konzept ist und mir egal ist, welche Sprache ich hier verwende):

%Vor%

Dies startet die Einfügungen, aber das Problem ist, dass es sehr viel Zeit braucht, um die Tabelle zu füllen (ich habe keine genaue Zeit, aber sie hat stundenlang gelaufen). Also, meine Frage läuft darauf hinaus: Gibt es eine einfache und effiziente Möglichkeit, eine MySQL-Tabelle mit einer Massenmenge von Zeilen wie dieser zu füllen?

    
user17753 08.10.2012, 19:50
quelle

4 Antworten

11

Im Allgemeinen können Sie einen oder mehrere der folgenden Punkte verwenden:

  • Starten Sie eine Transaktion, führen Sie Einfügungen durch, committen Sie
  • Packen Sie mehrere Werte in eine einzelne Einfügung in die Abfrage
  • Löschen Sie alle Abhängigkeiten, bevor Sie Integritätsbedingungen nach der Masseninsertion einfügen und wiederherstellen (mit Ausnahme des Primärschlüssels, dessen Unsicherheiten nicht bekannt sind)
  • Verwenden Sie insert into ... select falls geeignet

Der erste (mit Transaktionen) ist am ehesten hilfreich, aber ich bin nicht sicher, ob es auf myisam -Tabellen funktioniert, mit innodb macht es einen sehr guten Job - ich benutze nur solche, wenn ich gezwungen bin, mysql zu benutzen, Ich bevorzuge postgresql.

In Ihrem speziellen Fall können Sie 100000 Datenzeilen einfügen, indem Sie Folgendes tun:

%Vor%

Getestet auf meinem Rechner, habe:

%Vor%

Ich bin mir ziemlich sicher, dass Sie nicht viel schneller als das für 100000 Zeilen bekommen können.

    
xception 08.10.2012, 20:36
quelle
8

Wie wäre es, AUTO_INCREMENT auf den Primärschlüssel zu setzen?

Dann fügen Sie die ersten hundert (oder tausend) Zeilen ein, wie Sie möchten (Ihr Beispiel oder das Beispiel, das DocJones Ihnen gegeben hat).

Dann mit

%Vor%

... immer wieder ein paar Mal. Dies sollte die Tabelle jedes Mal doppelt so groß machen.

Das NULL im ersten Slot von SELECT stellt sicher, dass AUTO_INCREMENT eingeht und id inkrementiert.

Wenn du den Tisch sogar noch feiner werden willst, kannst du

machen %Vor%

... wiederholt ein paar Mal, wodurch die Tabelle mit Zweierpotenzen der vorherigen Größe + vorherige Größe (100 ^ 2 + 100) größer wird.

Damit können Sie auch die eingegebenen Werte anpassen, wenn Sie zum Beispiel "zufällig" responseCodes erstellen wollen. Sie können etwas wie CONCAT(ROUND(1+RAND()*4), '0', ROUND(RAND()*5)) verwenden, was Ihnen Antwortcodes von 100 bis 505 gibt.

    
Mihai Stancu 08.10.2012 20:27
quelle
2

PHP-Lösung, um sie in Chargen von 100 zu laden:

%Vor%     
Barmar 08.10.2012 21:24
quelle
1

Sie erstellen eine GROSS geschriebene Anweisung, die ausgeführt werden soll. Versuchen Sie es in kleineren Paketen zu zerlegen, z. Rufen Sie executeBatch () alle 1000 Inkremente von i (mit mod (i) yaddayadda) innerhalb der Schleife auf. Das sollte den Prozess beschleunigen:

%Vor%     
DocJones 08.10.2012 19:56
quelle

Tags und Links