2012-10-09 14 views
7

Das Skript, an dem ich arbeite, wurde entwickelt, um eine Datenbanktabelle zu aktualisieren, die das Land der Verwendung und den Status aller IP-Adressen (oder fast aller) aufzeichnet. Momentan behalte ich es einfach und hole nur Daten von den 5 RIRs (regionale Internet Registries) und speichere diese in meiner Datenbank.Änderung der Geschwindigkeit der SQL-Einfügungen

Anfangs waren die Geschwindigkeiten nicht praktikabel, aber sie wurden deutlich verbessert, indem die Menge der Informationen im Protokoll reduziert und die SQL-Einfügungen in Gruppen von 1000 gruppiert wurden und eine einzige Abfrage verwendet wurde. Wenn ich das Skript jetzt ausführe, bekomme ich sehr große Schwankungen in der Geschwindigkeit der SQL-Einfügungen und ich fragte mich, ob jemand wüsste warum.

Hier sind einige der Geschwindigkeiten, die ich aufgezeichnet habe. Im Test habe ich die Zeit für die Ausführung der Iterationen des Skripts in PHP und die Zeit für die Anwendung der SQL-Anweisung getrennt. Ich habe die PHP-Zeiten nicht in die Liste aufgenommen, da der Effekt vernachlässigbar war. nicht einmal 1 Sekunde für die größten Datenblöcke.

Prüfdrehzahlen (Anzahl der Datenzeilen eingefügt ist gleich bleibt in)

Test 1 Gesamt SQL Ausführen Zeit: 33 Sekunden

Test 2 Gesamt SQL Ausführen Zeit: 72 Sekunden

Test 3 Tota l SQL Ausführungszeit: 78 Sekunden

Andere Tests schwankten weiter zwischen ~ 30 Sekunden und ~ 80 Sekunden.

Ich habe zwei Fragen:

1) Soll ich diese Unterschiede als die Art und Weise der Welt übernehmen, oder gibt es einen Grund für sie?

2) Ich war nervös, weil ich die ~ 185000 Zeileneinsätze in eine Abfrage eintauchten. Gibt es einen Grund, warum ich vermeiden sollte, eine Abfrage für diese Einsätze zu verwenden? Ich habe nicht mit dieser Datenmenge gearbeitet, die vorher gespeichert wurde.

Danke

__

Die Datenbanktabelle ist wie folgt.

Sorage Engine - InnoDB

Spalten:

id - int, Primärschlüssel

Register - VARCHAR (7)

code - VARCHAR (2)

Typ - varchar (4)

Start - varchar (15)

Wert - int

Datum - Datumzeit

Status - varchar (10)

+0

Es gibt eine konfigurierbare maximale Länge für Befehle in MySQL - der Standard ist 1 MB. Mit 185.000 Zeilen könnten Sie dieses Limit erreichen. Sie können es natürlich erhöhen, und ich weiß nicht, warum Sie nicht sollten. – Argeman

+0

Ich nehme an, Sie verwenden Standard-Innodb-Tabelle Typ? – Argeman

+0

80 Sekunden für einen Einsatz, sogar 1000 Zeilen, klingt sehr lang. Ich breche oft in Gruppen von 100 auf und sie passieren schnell genug ("sofort" ish), dass ich mir nie Sorgen gemacht habe - das würde ich mit 1000 Reihen ähnlich erwarten. Faktoren, die es verlangsamen könnten - Netzwerkverkehr (aber nicht 80 Sekunden Arbeit), zu viele Indizes (wieder nicht genug Zeit) und Auslöser (haben Sie irgendwelche?). Aber du solltest viel, viel schneller als das bekommen - ich würde tiefer graben. Aber vergleichen Sie 100 vs 1000 vs 10.000, bevor Sie für das Los prall! – Robbie

Antwort

3
1) Should I accept these disparities as the way of the world, or is there a reason for them? 

Variationen der Geschwindigkeit kann aufgrund konkurrierender Prozesse sein die Verwendung von disk-IO - also auf Ressourcen warten. Wenn dies ein Produktionsserver ist, der kein einsamer Testserver ist, dann fordern sicherlich einige andere Prozesse Zugriff auf die Platte.

2) I felt nervous about lumping the ~185000 row inserts into one query. Is there any reason I should avoid using one query for these inserts? I've not worked with this amount of data being saved at one time before. 

Sie sollten die Inserts auch in Gruppen von X-Inserts aufteilen und jede Gruppe als Transaktion einfügen.

Den Wert von X anders als experimentell zu bestimmen, ist schwierig.

Durch die Gruppierung von Einfügungen in Transaktionen wird sichergestellt, dass Daten erst nach jeder Transaktion und nicht nach jeder (automatisch festgeschriebenen) Einfügung auf die Festplatte geschrieben (committed) werden.

Dies hat einen guten Effekt auf Disk-IO und wenn Sie zu viele Inserts in einer Transaktion gruppieren, kann es einen schlechten Effekt auf den verfügbaren Speicher haben. Wenn die Menge der nicht festgeschriebenen Daten für den aktuellen Speicher zu groß ist, beginnt das DBMS mit dem Schreiben der Daten in ein internes Protokoll (auf der Festplatte).

Also hängt X von der Anzahl der Einfügungen, der Menge der Daten, die mit jeder Einfügung verbunden sind, den erlaubten Speicher-/Benutzer-/Sitzungsparametern ab. Und viele andere Dinge.


Es gibt einige coole (freie) Werkzeuge von percona. Sie helfen Ihnen, die DB-Aktivität zu überwachen.

Sie können auch -n 0,5 ‚vmstat‘

Siehe die Menge und Variation von Daten bei vmstat Uhr schauen durch die Aktivitäten der Produktionsumgebung auf die Festplatte geschrieben werden.

Starten Sie Ihr Skript und warten Sie, bis Sie eine Erhöhung der Anzahl der auf die Festplatte geschriebenen Bytes feststellen. Wenn das Schreiben der Step-Ups so ziemlich ein konstanter Wert ist (über der normalen Produktionsnutzung), dann schlägt es & Swapping, wenn es rhythmisch ist, dann schreibt es nur für Commits.

+0

AFAIK binäre Protokollierung ist eine Option. Es wird tatsächlich von Replikations-Setups verwendet, wenn sie binäre Replikationstechniken verwenden. –

+0

Vielen Dank. Es ist ein Produktionsserver, also macht es Sinn - ich bin glücklich, solange ich eine Idee habe, warum die Ergebnisse variieren. Ich habe Gruppen von 1000 Einfügungen pro SQL-Anweisung verwendet, aber jetzt habe ich diese auf 10000 erhöht, da die Daten in jeder Zeile so klein sind. Ich werde versuchen, die Ressourcennutzung dafür zu überwachen. Danke noch einmal. – Marvin

Verwandte Themen