Sie sind hier : sebastian1012.bplaced.net/ homepage-neu / kreuz-und-quer / tutorials-info-neuigkeiten-datenbank / sql_calc_found_rows-fuehrt-zu-unerklaerlichen-abstuerzen.php

SQL_CALC_FOUND_ROWS führt zu unerklärlichen Abstürzen

Heute mal ein Beitrag über ein Thema, das mir wochen- wenn nicht sogar monatelang Kopfzerbrechen bereitet hat. Und zwar fiel mein Server immer mal aus unerklärlichen Gründen aus. Die Prozesse hingen sich auf und Feierabend. Natürlich gab es keine Reproduzierbarkeit des Fehlers – teilweise lief der Server auch mehrere Tage in Folge problemlos und dann krachte es wieder. Wie immer ohne Einträge in Logs oder sonstwo. Nun endlich habe ich das Problem gefunden…

Natürlich war der Fehler hausgemacht. Doch wollte ich es nicht wahrhaben, wo ich doch jedes Script nochmal untersucht habe, mich durch eingesetzte Fremdscripte gewühlt habe, die Datenbanken penibel überprüft habe.
Kurz gesagt: Es lag an einer hier im Blog empfohlenen SQL-Anweisung: SQL_CALC_FOUND_ROWS.

Diese Anweisung ist ja eigentlich ganz nützlich, erspart sie doch eine zusätzliche Abfrage für die Gesamtanzahl an Datensätzen, wenn man das Gesamtergebnis auf mehrere Seiten aufteilt. Schon damals kamen in den Kommentaren Stimmen gegen diese Maßnahme auf.
Marcel meinte Bezug nehmend auf einen Blogbeitrag vom MySQL Performance Blog:

Bei so einfachen Tabellen die auch noch Keys auf jeder Spalte haben, wie bei mysqlperformance ist Count natürlich schneller – hier geht es aber definitiv um komplexere Queries als bei mysqlperforrrrrmance gezeigt.

Damit hat er Recht. Ich habe es ja nicht umsonst geschrieben. Bei komplexen Abfragen wie Suchen mit MATCH oder LIKE-Funktion, GROUPing usw. spart SQL_CALC_FOUND_ROWS schon Zeit. Die eine Abfrage dauert zwar minimal länger, aber man spart sich eben eine zusätzliche Abfrage, die nur das Zählen der Gesamtzahl der Datensätze übernimmt.

Alex wies dann daraufhin, dass tatsächlich durch SQL_CALC_FOUND_ROWS ein Mehraufwand entsteht (weil ich ursprünglich geschrieben habe, dass kein Mehraufwand entstehen würde). Außerdem beschrieb er, dass es durchaus Abfragen gibt, die mit 2 Abfragen schneller sind als mit einer SQL_CALC_ROWS-Abfrage. Das stimmt natürlich (siehe oben).

Um zurück zu den Abstürzen zu kommen: Ich suchte also das gesamte Netz durch, weil man ja eigentlich nie der erste ist, der ein bestimmtes Problem hat. Irgendwann hab ich dann vor lauter Verzweiflung mal auf meinen eigenen Blogbeitrag geklickt – eben jenen zu SQL_CALC_FOUND_ROWS.
Und da lese ich mir die Kommentare durch und stoße auf den von mydeams:


In dem Projekt wo ich diese Methode genutzt habe, werden sehr viele MySQL Abfrage erstellt. ca. 1000 besucher hat die Seite am Tag. Mir/Uns ist aufgefallen, dass die Seite bzw. die MySQL DB sich nach na Zeit aufgehangen hat. Wegen dieses befehls. Habe ich das in der alten konventionellen Art gemacht mit nem entsprechendem Count … traten die Abstürze nimmer auf.

In der Prozessorliste von PHPMyAdmin hing er sich immer im Prozess “copy to tmp table” auf. Ich muss dazu aber auch sagen, dass die MySQL abfrage recht mächtig war, mit LIKE, LEFT JOIN etc. pp.

Ich griff also damit nach dem letzten Strohhalm und ersetzte alle SQL_CALC_FOUND_ROWS-Befehle durch die traditionelle 2-Abfragen-Methode mit COUNT().
Und das unglaubliche trat ein: Wie von mydeams prophezeit hatten die Abstürze dadurch tatsächlich eine Ende. Ein ganz großes Dankeschön an dieser Stelle! Deshalb freue ich ich über jeden Kommentar – er kann mal noch seeehr nützlich werden!

Ergo ziehe ich meine Empfehlung von SQL_CALC_FOUND_ROWS wieder zurück. Ob es an meiner Konfiguration lag, ob MySQL einen Bug hat, ich weiß es nicht. Ich weiß aber, dass ich in Zukunft einen großen Bogen um diese Funktion mache, denn es ist mir jetzt auch egal, ob der Seitenaufbau bei der Suche nun 0,2 Sekunden länger dauert, denn Performanceoptimierung darf natürlich nie auf Kosten der Stabilität gehen.