MySQL-Ressourcen freigeben

Kaum jemand erinnert sich gern an die hardwarenahe Programmierung in Assembler oder C, wo jeder Speicherbereich einzeln reserviert werden musste. In Scriptsprachen wie PHP ist das nicht mehr nötig, sondern wird intern erledigt. Doch jede Automatik kostet etwas: Beim Auto mit Automatikschaltung ists der höhere Spritverbrauch und bei der automatischen Speicherverwaltung von PHP ists der höhere Speicherverbrauch. Dieser Beitrag soll zeigen, wie PHP mit Speicherressourcen umgeht und wie man dies optimieren kann.

Schaut man sich die Dokumentationen der Funktionen mysql_close() sowie von mysql_free_result() an, erfährt man, dass beide Funktionen eigentlich unnötig sind. So werden offene Verbindungen am Ende des Scripts automatsich geschlossen (lediglich auf den Einsatz in Frames wird verwiesen) und auch Result-Ressourcen werden zu diesem Zeitpunkt automatisch wieder freigegeben. Alles bestens – oder?

Eben nicht, denn es gibt Einsatzgebiete, wo diese Funktionen sinnvoll für einen schnelleren Seitenaufbau genutzt werden können. Und sauberer ists ja sowieso – auch wenn dieses Argument leider heutzutage oft nichts mehr zählt.
Zuerst widme ich mich mysql_close(). Diese Funktion schließt eine offene Verbindung zu einer MySQL-Datenbank. Wenn man nur einfach eine PHP-Datei abarbeitet, bringt es tatsächlich nicht viel, weil PHP dann einfach feststellt, ob die Verbindung noch länger gebraucht wird. Und wenn nicht, dann wird der entsprechende Speicherbereich freigegeben (Garbage Collection)
Wenn man aber beispielsweise dynamisch Thumbnails erstellt (mit den PHP-Image-Funktionen) oder andere eingebettete Sachen macht, kann das Freigeben durchaus Geschwindigkeitsvorteile bringen (hat es zumindest bei mir).

Auch wenn man mehrere Datenbanken nutzt, kann mysql_close() durchaus sinnvoll sein, wenn die Daten aus der einen nur am Anfang des Scriptes benötigt werden. Dann kann nämlich die Verbindung nach Ihrer letzten Benutzung geschlossen werden, während das Script noch fleißig mit der anderen Datenbank weiterarbeitet.

Und nun zu mysql_free_result(). Diese Funktion gibt Ressourcen wieder frei, die von einer SELECT-Anfrage belegt wurden. Dies macht insbesondere dann Sinn, wenn man große Ergebnismengen verarbeitet. Verarbeiten bedeutet hier, dass diese von MySQL an PHP gesendet werden. Was MySQL intern macht, ist hier egal. So ein unnötig reservierter 50-MB-Block im Speicher wirkt sich je nach Speicherausstattung durchaus ungünstig aus – 50 MB pro Besucher versteht sich. Und aus diesem Grund ist es oft auch besser speicherintensive Operationen (Zählen, Rechnen, Aggregieren) direkt vom DBMS erledigen zu lassen, da dieses dafür optimierte interne Funktionen bietet. Nach größeren SELECT-Querys darf man also ruhig auch mal den dafür verwendeten Speicher wieder freigeben.
Ein Kommenatr von Nairebis bei php.net zeigt, dass die Funktion durchaus sinnvoll sein kann:

ALWAYS use this function! I just encountered a bug in my code where I forgot to use this function. I also happen to be using mysql_pconnect() for a persistent connection. If you forget to free the result, it can hold the old result set open indefinitely within the HTTP process.

Denkt einfach mal drüber nach. Vielleicht erspart es euch die eine oder andere Stunde Verzweiflung. Und dann testet es einfach mal aus, auch wenn die Doku das nicht wirklich empfiehlt, aber ich für meinen Teil habe damit durchaus positive Erfahrungen gemacht.



Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0