Christian Kruse: PHPMyAdmin

Beitrag lesen

Hallo Martin,

danke auch von meiner Seite für die ausführliche und einleuchtende Erklärung. Eine Sache bleibt aber trotzdem noch mysteriös, finde ich: Auch wenn die Anzahl der Datensätze aus Statistik-Daten "geschätzt" wird, sollte sich doch immer das gleiche Resultat ergeben, oder nicht?

Ich bin kein MySQL-Spezialist, bei PostgreSQL wäre das so, da werden die Statistiken in den System Catalogs gespeichert.

Aber soweit ich weiss arbeitet MySQL mit table samples, das heisst, dass es ein paar Pages von der Disk liest und anhand der Daten in den Pages und der Grösse der Relation auf der Platte auf die Tabelle schliesst. Die Page-Dichte allerdings variiert natürlich aufgrund von Faktoren wie Table Bloat und Füllmenge (nicht jede Page ist vollständig gefüllt).

Bzgl Table Bloat: der entsteht, wenn eine Zeile als gelöscht markiert werden muss. Das kann entweder passieren, wenn man sie via DELETE wirklich löscht oder wenn man sie mit einem UPDATE verändert. Es dürfte klar sein, warum bei einem DELETE die Zeile nicht entfernt wird: einerseits wieder wegen MVCC, andererseits ist das auch eine Performance-Frage. Man müsste ja die darauf folgenden Rows nach oben „schieben“ auf der Platte und alle eventuellen Index-Verweise ändern. Also wird stattdessen die Row als gelöscht markiert. Bei einem UPDATE gilt im wesentlichen das gleiche: die Reihe kann nicht einfach überschrieben werden, Stichwort MVCC. Also hängt man sie in einer neuen Version an die Tabelle an und markiert die alte Row als gelöscht.

Durch dieses Vorgehen entsteht sog. Table Bloat. Also im Grunde Löcher in den Tabellen-Files, die nicht benutzt werden können aber trotzdem gelesen werden müssen. Das ist der Grund, warum man regelmässig OPTIMIZE TABLE ausführen will. Was „regelmässig“ in diesem Fall ist hängt natürlich von der Anwendung ab: bei wenigen Schreibzugriffen ist das seltener nötig.

So, ich hoffe ich habe nichts vergessen…

LG,
CK