ich bin mir nicht sicher, ob das in diesen Bereich passt, wenn nicht bitte verschieben.
Ich habe eine DB mit ca 1500 Tabellen. Alle von einer Basistabelle geerbt in der Primärschlüssel und ein paar gemeinsame Attribute sind. Jetzt möchte ich eine größere Menge Daten einfügen, oder ändern. Dabei gehe ich wie folgt vor:
Lösche aus der Basistabelle die Zeile, die zum Primärschlüssel passt. (Kann auch sein, dass es gar keine zum Löschen gibt.)
Füge die neue Zeile in die Zieltabelle ein.
(INSERT OR UPDATE gibt es ja so nicht…)
Jetzt dauert aber das Suchen, ob und was zu löschen ist sehr lange. Einen separaten Index über den Primärschlüssel habe ich auch schon angelegt.
Du hast eine Basistabelle, von der dann ca. 1500 abgeleitet sind? Die Basistabelle enthält auch Daten? Ist das Partitionierung? Ist Constraint Exclusion eingeschaltet, welche Version hat die DB? Kannst Du mal ein EXPLAIN bzw. EXPLAIN ANALYSE zeigen? Über wieviel Datensätze reden wir eigentlich?
Constraint Exclusion - das war das Stichwort. Werde ich gleich ausprobieren.
EXPLAIN:
“Delete on basis_tabelle (cost=0.00…7855.58 rows=953 width=6)”
" -> Seq Scan on basis_tabelle (cost=0.00…0.00 rows=1 width=6)"
" Filter: (((key1)::text = ‘test’::text) AND ((key2)::text = ‘test’::text))"
" -> Index Scan using t1_pkey on t1 basis_tabelle (cost=0.00…8.27 rows=1 width=6)"
" Index Cond: (((key1)::text = ‘test’::text) AND ((key2)::text = ‘test’::text))"
" -> Index Scan using t2_pkey on t2 basis_tabelle (cost=0.00…8.27 rows=1 width=6)"
" Index Cond: (((key1)::text = ‘test’::text) AND ((key2)::text = ‘test’::text))"
usw. bis Zeile 1900
Danke für die schnelle Hilfe!
Würde es schneller gehen, wenn ich vorher über einen SELECT rausfinde, ob es überhaupt etwas zu löschen gäbe?
Also (pseudocode):
IF SELECT xy FROM basis_tabelle WHERE …
DELETE FROM … WHERE …
ENDIF;
Constraint Exclusion bringt nur was, wenn passende Constraints auf dem Kind-Tabellen gesetzt sind. Bei Deiner Abfrage scheint mir das eher nicht der Fall zu sein. Aber meine Glaskugel ist grad zur Reparatur.
Würde es schneller gehen, wenn ich vorher über einen SELECT rausfinde, ob es überhaupt etwas zu löschen gäbe?
Also (pseudocode):
IF SELECT xy FROM basis_tabelle WHERE …
DELETE FROM … WHERE …
ENDIF;
Nein, vermutlich ca. doppelt so lange.
Nachtrag: kommt drauf an, wie viele Treffer es gäbe. Bei nur sehr wenigen würde es nicht viel langsammer als jetzt gehen. Vermutlich.
1500 Tabellen hört sich jetzt jedenfalls nicht so toll an. Das erzeugt einigen Overhead beim Erstellen des Anfrageplans. Kann sein, das du mehr Zeit in der Vorbereitung der Anfrage verbringst als letztendlich in der Ausführung.