Verzögerte Inserts für MySQL – Insert Delayed

Wenn man ein fertiges Webprojekt übernimmt, kann man manchmal sein blaues Wunder erleben. Man überlegt sich desöfteren wo der Webworker, der zuvor an dem Projekt gearbeitet hat, sein Handwerk gelernt hat. Nicht normalisierte Datenbanken und daraus resultierend Queries die an Langsamkeit wohl nicht zu überbieten sind, sind da zumeist Standard. Zumeist lassen sich Anwendungen explosionsartig verschnellern, wenn man Indizes in die Datenbank einfügt.

Es gibt allerdings auch ein paar Nettigkeiten, wo sich der Webworker an sich Gedanken machen sollte, das MySQL garantiert Probleme machen wird. Mein Favorit sind da Datenbanken, die jede Pageimpression speichern, oder jedes Suchwort in der selbst gebastelten Suchmaschine. MySQL/PHP besitzt da nämlich eine Eigenart, die recht einfach zu umgehen ist: Füge ich mittels Insert etwas in die Datenbank ein, so geht es mit der Code-Ausführung erst dann weiter, wenn MySQL mitgeteilt hat, das es garantiert und sicher die Daten gespeichert hat.

Wie man sich vorstellen kann, ist dies nicht gut! Vor allem wenn man InnoDB mit vielen Foreign Keys verwendet, kann der Insert an sich eine Sache sein, die nicht schnell erledigt ist und Seiten langsam machen. Vor allem ist es zumeist so, dass bei den meisten Daten die man in die Datenbank einfügt, diese nicht wieder sofort abrufen muss (eben bei Logs, oder einer Statistik von Suchwörtern), sondern das es ausreicht, das die Daten „irgendwann mal auftauchen“.

Aufgrund dieser Problematik besitzt MySQL den Befehl INSERT DELAYED! Benutzt man diesen Befehl, wird der Insert „irgendwann, wenn Zeit ist“ ausgeführt, und MySQL stellt diesen in eine Queue. Dafür meldet es der Anwendung sofort zurück, das der Insert erfolgt ist – ohne jegliche Verzögerung. Der Syntax entspricht bis auf das Delayed exakt einem „normalen“ Insert.

Kleines Wort – große Wirkung ;)

3 Kommentare

  • Dass das bei InnoDB nicht geht ist ja auch irgendwo logisch, da gibt es Transactions und erst der Commit löst den eigentlichen Insert aus – dort könnte man so vorgehen das man den Commit etwas geschickter auslöst als sonst, und nicht dann wenn die Transaction fertig ist ;) Ist zum Beispiel Quatsch nach jedem Insert ein Commit auszuführen, einer am Ende – wenn man fertig ist – reicht in der Regel auch.

  • Das Beispiel mit InnoDB oben passt leider nicht ganz, denn gerade InnoDB kann KEIN insert delayed, sondern nur MyISAM, Archive und Memory.

    Und auf InnoDB möchte ich mangels Transaktionen, Fremdschlüsseln etc. nur ungern verzichten.

Schreibe einen Kommentar