MySQL - Update im Hintergrund ausführen

Martin J

Aktives Mitglied
Hi,

ich habe eine recht datenbanklastige Anwendung, basierend auf der Perl-DBI und Mysql 5.1. Es werden sehr viele UPDATE Anweisungen produziert, die mittlerweile den Bottleneck der Anwendung darstellen. Das Ergebnis der UPDATE Anweisung ist nicht kritisch, es muss nicht sofort, sondern nur zeitnah aktualisiert werden und selbst wenn mal etwas verloren ginge, wäre es nicht schlimm.

Meine Frage: Bei INSERT gibt es ja die Möglichkeit DELAYED anzugeben und nicht auf das Resultat zu warten. Bei UPDATE gibt es soetwas nicht.

Hier sind ja ein paar SQL Spezialisten versammelt, vielleicht habt ihr einen Tipp, welcher Ansatz Sinn machen würde, bzw. wo man vielleicht sauf schon bestehende Klassen zurückgreifen kann:
  • Updates innerhalb der Anwendung sammeln und periodisch mehrere auf einmal ausführen
  • einen externen Daemon oder so einrichten, der an einem Socket lauscht und selber eine Queue bildet, so dass die eigentliche Anwendung mit voller Geschwindigkeit weiterläuft
  • Lösungen in MySQL direkt (Speicherbasierte Tabellen, andere Engines...)
Die Datenbank und die Indizes sind bereits alle optimal, auch der Server selbst ist grundsätzlich einigermassen passend konfiguriert.

vg,
martin
 
Eigentlich sind das noch zu wenige Informationen, um das Problem brauchbar zu identifizieren.

Bsp.:
- Das Update einer einzelnen Zeile kann zu lange dauern, weil Indices fehlen / falsch sind.
- Bei der Ausführung einer Seite werden 20 Datensätze geholt und die zeilenweise aktualisiert - anstatt in einem Rutsch.
- Die Ermittlung der neuen Werte ist aufwendig, blockiert, weil parallel schon wieder andere Updates laufen.
- Der Server ist insgesamt unterdimensioniert, das Problem tritt nur eher zufällig bei den Update-Anweisungen auf.


Technisch kann man bsp. die zu aktualisierenden Daten in eine neue Tabelle schreiben. Zusätzlich läuft irgendeine Dauerschleife, die diese Tabelle überwacht, die Updates vornimmt und die verarbeiteten Zeilen löscht. Dann wäre das völlig entkoppelt. Oder man schreibt die zu aktualisierenden Werte in eine zusätzliche Tabelle und macht das Update im folgenden Schritt. Damit sind Updatesperre und Select-Sperre zur Ermittlung der neuen Werte voneinander entkoppelt.

Beim MS-SqlServer kann man 'Dirty Reads' zulassen. Damit müssen Abfragen, die Werte zurückgeben, nicht auf die Fertigstellung von Änderungen warten. Theoretisch können dann zwar ab und an fehlerhafte Werte zurückgegeben werden, aber das könnte (laut den Hinweisen) tolerierbar sein.
 
QUOTE (jAuer @ Fr 25.04.2008, 20:44) Eigentlich sind das noch zu wenige Informationen, um das Problem brauchbar zu identifizieren.
...
Technisch kann man bsp. die zu aktualisierenden Daten in eine neue Tabelle schreiben. Zusätzlich läuft irgendeine Dauerschleife, die diese Tabelle überwacht, die Updates vornimmt und die verarbeiteten Zeilen löscht. Dann wäre das völlig entkoppelt. Oder man schreibt die zu aktualisierenden Werte in eine zusätzliche Tabelle und macht das Update im folgenden Schritt. Damit sind Updatesperre und Select-Sperre zur Ermittlung der neuen Werte voneinander entkoppelt.


Ok, vielen Dank für die Tipps so weit.

@Sven:
da habe ich auch zuerst geschaut, aber in der MySQL Doku steht:

QUOTE Wenn Sie das Schlüsselwort LOW_PRIORITY  angeben, wird die Ausführung von UPDATE  verzögert, bis kein Client mehr aus der Tabelle liest.


Hier stehts nochmal etwas expliziter: http://osdir.com/ml/db.mysql.general/2002-06/msg01049.html (wobei ich mich liebend gerne vom Gegenteil überzeugen liesse)

@jAuer (Dein SQL Tutorial ist schön)
Ein paar von den von Dir genannten Sachen kann ich ausschliessen:
Indizes sind ok
Ermittlung neuer Werte ok (werden mittels fetchall schon vorher in den Speicher gelesen)
Server (Hardware als auch mysqld) ok

Aus Deinen anderen Punkten werde ich jetzt erstmal die neue Tabelle und das Zusammenfassen der Updates aufgreifen.
Ich werde mal testweise die Inserts in eine temporäre Tabelle im Speicher schreiben und dann periodisch als Updates auf einmal einspielen. Das dürfte deutlich einfacher sein, als den Dämon zu schreiben.
smile.gif


Ich schreibe dann mal in einer Woche, ob es sich gelohnt hat.

MsSql kenne ich leider nicht, da ich im Laufe der Jahre vieles auf Unix optimiert habe. Zumindest Stand 2006 war MySQL (>5.0) für meine Zwecke besser geeignet, als Postgres oder die kleine Oracle Version.
 
QUOTE (Martin J @ Fr 25.04.2008, 21:19)Aus Deinen anderen Punkten werde ich jetzt erstmal die neue Tabelle und das Zusammenfassen der Updates aufgreifen.
Ich werde mal testweise die Inserts in eine temporäre Tabelle im Speicher schreiben und dann periodisch als Updates auf einmal einspielen. Das dürfte deutlich einfacher sein, als den Dämon zu schreiben.
smile.gif



Ich hatte da eigentlich bloß an einen einfachen Cronjob gedacht. Nicht gleich ein eigener Dämon.


QUOTE (Martin J @ Fr 25.04.2008, 21:19)@jAuer (Dein SQL Tutorial ist schön)


danke für das Lob. Und schön, wenn die Texte nützlich sind und Leser finden.
 
Nebenbei bemerkt: Die gesamte Seite ist sehr lesenswert. Da schreibt jemand mit Ahnung von der Materie.
 
Zurück
Oben