(Oracle) Subselect für Update soll pk zurück liefern und bringt mich um den Verstand

Ohne weitere Indexe (Nur den STD primary Key UPE_PK)
Das Thema Indexe ist eine meiner nä. Baustellen...

Bisher war ich noch nicht in der Verlegenheit sonderlich zeitkritisch zu sein.
Erst seit ich vorhandenes Datenmaterial eingespielt habe, merkt man die ersten Wartezeiten...

lG.
Atlantis
 
Das mekrt man meistens erst mit wachsenden Daten.

Da hast du aber noch etwas gefährliches im Code.
Im GROUP BY hast du ein Feld, dass du nachher nicht vergleichst. UPE_QUELLE

Die folgende Lösung könnte schneller sein, da zuerst gefiltert wird und dann erst Gruppiert
SQL:
UPDATE t_trad_upe_sb dst
SET dst.maxwert = (
        select CASE WHEN dst.upe = MAX(src.upe) THEN 1 ELSE 0 END
        FROM t_trad_upe_sb src
        WHERE dst.z_tln = src.z_tln AND dst.gueltig_ab = src.gueltig_ab AND dst.upe_quelle = src.upe_quelle
        GROUP BY src.z_tln, src.gueltig_ab, src.upe_quelle
    )
 
Hallo Yaslav

Habe das von Dir optimierte SQL Statement gerade nach 71.830 Sekunden abgebrochen.

Jetzt ist wohl die Zeit gekommen sich dem Thema Index zu widmen.
Ich werde mal die Tage nach dem Thema Index & Tutorial suchen...

Danke Dir noch einmal für den super Service.
Eine schöne Weihnachtszeit

Atlantis
 
Bei fast 2 Millionen Einträgen sind Indexe überfällig.
Ist wie ein Buch ohne Inhalts- und Stichwortverzeichniss mit 2 Mio Seiten.
 
Moin Atlantis,

habe gerade eben erst diesen Thread entdeckt.
Falls es noch nicht erledigt ist, versuche es mal so:

SQL:
MERGE INTO T_TRAD_UPE_SB dst
      USING (SELECT src.Z_TLN
           , src.GUELTIG_AB
           , max(src.UPE) AS MAX_VAL
    FROM T_TRAD_UPE_SB src
    GROUP BY src.Z_TLN
             , src.GUELTIG_AB
             , src.UPE_QUELLE
    ) src ON (dst.Z_TLN = src.Z_TLN
     AND dst.GUELTIG_AB = src.GUELTIG_AB
     AND dst.UPE = src.UPE)
     
   WHEN MATCHED
        UPDATE SET dst.MAXWERT = 1
   WHEN Not MATCHED
        UPDATE SET dst.MAXWERT = 0

Grüße
Biber
 
Moin Yaslaw,

ich sach ma' so...
Hier in diesem Fall ist es eine vollkommen hypothetische Frage.
Der TE will in einer Tabelle mit 2 Mio Datensätzen jeden, aber auch jeden Datensatz updaten.
Ich hätte - da es ja eine Initialbefüllung zu sein scheint, ohnehin erst alle Datensätze auf MAXWERT=0 gesetzt oder wahrscheinlicher noch den Default für dieses Feld auf "NOT NULLABLE WITH Default =0" geändert.
Damit wären 1, 9 Mio Datensätze korrekt auf "nicht die aktuellen" gesetzt und die verbleibenden 100000 hätte ich mit dem MERGE-Update auf 1 gesetzt. Also Statement oben ohne "WHEN NOT MATCHED".

Aber zurück zu deiner Frage:
- ja, MERGE ist nach meiner Wahrnehmung relativ schnell
- aber auch Merge kann natürlich nur Indexe nutzen, die vorhanden sind (also wird er ohne Indizes auch nicht schneller sein als deine Varianten oben)

Hauptgrund, weshalb ich den MERGE INTO hin und wieder verwende ist, dass Oracle die Verwendung von CTEs (also "WITH TableX as (select...)" bei SELECT, INSERT, DELETE unterstützt, nicht aber bei UPDATE-Operationen.

Dort wäre das Pendant zu einer WITH-Syntax eben das verwendete "USING (...)", in dem common table expressions verwendet werden können.

und ein weiteres Goodie ist die Möglichkeit, bei MERGE INTO nicht nur UPDATEs machen zu können, sondern z.B. im Fall "WHEN NOT MATCHED" auch ein INSERT eines neuen Satzes machen zu können.

Unterm Strich: ja, ich halte MERGE INTO für schnell und empfehle mal das Ausprobieren.

Grüße
Biber
 
Merci für die Erläuterungen.
ich kenne Merge. Mir wäre es aber nicht in den Sinn gekommen ihn für einen reinen Update anzuwenden. Aber deine Erklärung ist gut. Ich merke diese Idee mal.
 
Zurück