Ist Postgres besser als MySql, wenn man einer Tabelle mit Millionen von Zeilen eine Spalte hinzufügen muss?

8

Wir haben Probleme mit Mysql. Wenn ich herumsuche, sehe ich, dass viele Leute das gleiche Problem haben.

Ich habe mit einem Produkt zusammengearbeitet, bei dem die Datenbank einige Tabellen mit bis zu 150 Millionen Zeilen enthält. Ein Beispiel für unser Problem ist, dass eine dieser Tabellen über 30 Spalten hat und etwa die Hälfte davon nicht mehr verwendet wird. Wenn Sie versuchen, Spalten zu entfernen oder Spalten umzubenennen, möchte mysql die gesamte Tabelle kopieren und umbenennen. Bei dieser Datenmenge würde dies viele Stunden dauern und die Seite wäre praktisch die ganze Zeit offline. Dies ist nur die erste von mehreren großen Migrationen, um das Schema zu verbessern. Diese sind nicht als normale Sache gedacht. Nur eine Menge Aufräumen, die ich geerbt habe.

Ich habe versucht zu sehen, ob Leute das gleiche Problem mit Postgres haben und ich finde fast nichts im Vergleich zu diesem Thema. Ist das, weil Postgres viel besser darin ist, oder nur, dass weniger Leute postgres benutzen?

    
Andrew 22.12.2010, 22:22
quelle

3 Antworten

18

In PostgreSQL wird eine neue Spalte ohne Standardwert zu einer Tabelle hinzugefügt, da die neue Spalte nur im Systemkatalog registriert ist und nicht tatsächlich auf der Festplatte hinzugefügt wird.

    
Peter Eisentraut 23.12.2010 05:13
quelle
12

Wenn das einzige Werkzeug, das Sie kennen, ein Hammer ist, sehen alle Ihre Probleme wie ein Nagel aus. Für dieses Problem ist PostgreSQL viel besser im Umgang mit diesen Arten von Änderungen. Und Tatsache ist, es spielt keine Rolle, wie gut Sie Ihre App entworfen haben, Sie werden das Schema in einer Live-Datenbank irgendwann ändern müssen. Während die verschiedenen Engines von MySQL für bestimmte Fälle wirklich erstaunlich sind, hilft hier keiner von ihnen. PostgreSQLs sehr enge Integration zwischen den verschiedenen Schichten bedeutet, dass Sie Dinge wie transaktionale ddl haben können, mit denen Sie alles zurücksetzen können, das keine alter / create Datenbank / Tablespace ist. Oder sehr, sehr schnell Alter Tabellen. Oder nicht behindernde Indizes erstellen. Und so weiter. Es beschränkt PostgreSQL auf die Dinge, die es gut macht (traditionelles transactional db load handling ist ein starker Punkt) und nicht so gut bei den Dingen, die MySQL oft füllt die Lücken, wie live vernetzten Clustered Storage mit der ndb-Engine.

In diesem Fall können Sie mit keiner der verschiedenen Engines in MySQL dieses Problem lösen. Die Vielseitigkeit von mehreren Speicher-Engines bedeutet, dass der Lexer / Parser / Top-Layer der DB nicht so eng in die Speicher-Engines integriert werden kann und daher viele der coolen Dinge, die pgsql hier tun kann, nicht tun kann.

Ich habe eine 118Gigabyte Tabelle in meinen Statistiken db. Es hat 1,1 Milliarden Zeilen. Es sollte wirklich partitioniert werden, aber es wird nicht viel gelesen, und wenn es ist, können wir darauf warten. Bei 300 MB / s (die Geschwindigkeit, mit der das Array gelesen werden kann) dauert das Lesen etwa 118 * ~ 3 Sekunden oder etwa 5 Minuten. Diese Maschine hat 32 Gigabyte RAM, so dass sie die Tabelle nicht im Speicher halten kann.

Wenn ich die einfache Anweisung in dieser Tabelle ausgeführt habe:

alter table mytable füge Testtext hinzu;

es hing warten auf ein Vakuum. Ich habe das Vakuum beendet (wähle pg_cancel_backend (12345) (& lt; - pid da drin) und es ist sofort beendet. Ein Vakuum auf diesem Tisch braucht viel Zeit, um zu laufen. Normalerweise ist es keine große Sache, aber wenn man Änderungen am Tisch vornimmt Struktur, müssen Sie auf Staubsauger warten oder sie töten.

Das Löschen einer Spalte ist genauso einfach und schnell.

Nun kommen wir zu dem Problem mit postgresql, und das ist der MVCC-Speicher im Heap. Wenn Sie diese Spalte hinzufügen, führen Sie eine Aktualisierungstabelle aus. Set = 'abc' aktualisiert jede Zeile und verdoppelt die Größe der Tabelle. Sofern HOT die Zeilen nicht aktualisieren kann, benötigen Sie eine Tabelle mit 50% Füllfaktor, die zunächst doppelt so groß ist. Der einzige Weg, um den Raum zurück zu bekommen, ist entweder warten und lassen Sie Vakuum es im Laufe der Zeit zurückgewinnen und es ein Update zu einem Zeitpunkt wiederverwenden, oder Cluster oder Vakuum voll ausführen, um es zurück zu verkleinern.

Sie können dies umgehen, indem Sie Aktualisierungen für Teile der Tabelle gleichzeitig ausführen (update wo pkid zwischen 1 und 10000000; ...) und zwischen jedem Durchlauf Vakuum erzeugen, um den Speicherplatz zurück zu gewinnen.

Also, beide Systeme haben Warzen und Unebenheiten zu bewältigen.

    
Scott Marlowe 24.12.2010 05:04
quelle
-3

vielleicht, weil dies kein reguläres Ereignis sein sollte.

vielleicht, lesen zwischen den Zeilen, müssen Sie eine Zeile zu einer anderen Tabelle hinzufügen, anstatt Spalten zu einer großen vorhandenen Tabelle ..?

    
Randy 22.12.2010 22:28
quelle

Tags und Links