Effektives Update einer Tabelle mit 32Mio Datensätzen - wie?

Die Ursache dafür könnte durchaus sein, daß Deine gesammtes Datenmodell, ähm, Scheiße ist. Aber das haben ads und ich Dir schon vor einiger Zeit erklärt.


Dieser Befehl wurde innerhalb von 1,5h (!) durchgeführt. Es ist mir daher wirklich unverständlich, warum selbst der o.a. INSERT-Befehl zu Speicherproblemen innerhalb der Datenbank führen sollte…

Da sind DISTINCT-Operationen auf eine relativ große Datenmenge nötig. Möglicherweise ist schlicht und ergreifend Deine Platte voll und PG kann da keine temp. Dateien mehr anlegen.

Leider ist es aber so, dass es einige Ausnahmefälle gibt:

In allen Fällen enthält die kleine Tabelle Daten, die in art_id, store_id und dat_id mit einem jeweiligen Datensatz aus der großen Tabelle übereinstimmen.

Manche Artikel wurden aber im gleichen Geschäft am selben Tag bestellt (best.datum) und an unterschiedlichen Tagen bezahlt (bez.datum). Diese Tatsache erfordert eine Summenfunktion innerhalb des UPDATE-Befehls,

Und das ist der Punkt mit dem Datenmodell: warum einklich das UPDATE? Wenn Du die Programmlogik vielleicht mal ändern würdest, hättest Du das Problem vielleicht nicht.

Ich muss also irgendwie eine Summenfunktion in dem UPDATE-Befehl unterbringen können, oder eben die Summenfunktion in einem getrennten INSERT-Befehl ausführen. Leider ist lässt sich eine Summenfunktion aber eben NICHT in einem UPDATE-Befehl unterbringen - es sei denn, es gibt da ein paar Tricks? Diesbezüglich bin ich langsam mit meinem Latein am Ende…

Deine Auswertungen, zu denen ja offensichtlich die Tabelle gehört, auf die der Update zugreift, vielleicht mal komplett ohne Veränderung der Daten selbst durchführen. VIEWS existieren.


Andreas

Die Ursache dafür könnte durchaus sein, daß Deine gesammtes Datenmodell, ähm, Scheiße ist. Aber das haben ads und ich Dir schon vor einiger Zeit erklärt.

Wirklich konstruktiv, danke vielmals…

Um die restlichen Anregungen werde ich mich heute Abend kümmern…

Trotzdem danke.

Schon mal überlegt, dass akretschmer Recht haben könnte und dein Datenmodell wirklich - unzulänglich ist? Mit einem komplett anderen Ansatz könnte man sonst nämlich solche Monster Updates vielleicht vermeiden.

Du solltest das echt mal überlegen, und Dir auch mal überlegen, was da im Detail abläuft. Bedenke dabei u.a. das:

  • jede Zeile, die geupdatet wird, hinterläßt einen toten Tupel
  • wenn Du in einer Schleife innerhalb einer TX das mehrfach machst, das Du halt entsprechend viel davon.
  • all das läuft in einer TX, also wird da auch ein hinreichend großes Log für anfallen
  • für die Sortieroperationen (Distinct) ist wieder Speicher nötig, wahrscheinlich auf Platte
  • obige Punkte zusammengenommen: du hast sehr, sehr viel zu schreiben, was Zeit braucht, und nicht zu vergessen: Platz


    Du hast nun 2 Wege, das zu beschleunigen:
  • Du wirfst mit Geld und kaufst hinreichend Hardware (oder einen, der sich damit auskennt)
  • Du wirst mit Hirn um das Problem eleganter zu lösen



    Du kannst natürlich auch beleidigt tun, mir egal. Aber Dein Problem wird davon ganz sicher nicht gelöst, und mir ist es egal. Ganz echt.

Andreas

Korrekt, kann ich nur zustimmen.

Wir doktoren seit 3 Forumseitenan dem Problem herum, ohne das akretschmer oder ich wirklich wissen, was vor sich geht. Kein Query Plan, keine tiefgreifenden Details.

Wenn wir jedoch etwas sagen, was dir nicht passt, bist du beleidigt. Hey, wir machen das hier in unserer Freizeit, du hast nicht mal Anspruch darauf, dass jemand dir überhaupt antwortet. Für so etwas kauft man sich Support ein.

Wieso sollte das so sein ? JEDE wenn das Update des Tupel weniger oder genauso breit ist wie das alte gibt es keinen - aber auch garkeinen Grund des alten Tupel sterben zu lassen … und wenn das Update zudem auch keinen Index tangiert muss auch der Index nicht geupdated werden.

Wenn dem bei Postges dennoch so ist … ohje ohjemine :slight_smile:

Gruß

MVCC.

Andreas

Dir ist schon bewusst, dass diese “alten” Tuples ggf. noch für andere Transaktionen zur Verfügung stehen müssen und man diese demzufolge nicht einfach blind überschreiben kann?

Das nennt sich MVCC, wie akretschmer schon erwähnt hat.

Wenn du eine bessere Lösung für dieses Problem weisst, die Welt steht dir offen.


Bezüglich Index aktualisieren: ja, das stimmt. PG 8.3 bildet etwas ähnliches ab, indem in den Speicherseiten selbst eine Art Mini-Vacuum durchgeführt wird und der Speicherplatz wiederverwendet wird. Trotzdem muss erst mal für die Laufzeit der Transaktion(en) der neue Wert geschrieben und gleichzeitig der alte Wert bereitgestellt werden.

das ist aber ebenso kein Grund diese Tupel sterben zu lassen …

Das ist halt der alte Tupel, der zum Ende der Transaktion ungültig wird.
Wie möchtest du das anders lösen? In-place kannst du den Wert nicht überschreiben …