Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   FB 3.0 Update mit where exists durchläuft alle Record der upd tbl. (https://www.delphipraxis.net/215337-fb-3-0-update-mit-where-exists-durchlaeuft-alle-record-der-upd-tbl.html)

Kostas 14. Jun 2024 21:01

Datenbank: Firebird • Version: 3.0 • Zugriff über: FIREDAC

FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
Hallo Zusammen,

bei den beiden Nachstehenden Beispielen, liefert das Select auf die Rechnungen genau einen record.
Das Update aktualisiert auch nur den einen Record. Allerdings wird in beiden Beispielen die komplette Datenmenge von 500.000 Adressen durchlaufen. Das dauert natürlich. Das sehe ich auch in IBExpert unter Performance Analysis.


Code:
UPDATE ADRESSEN A
   SET A.AKTIV = 1
 WHERE EXISTS (SELECT NULL
                 FROM RECHNUNGEN R
                WHERE R.RECHNUNGSNR = 1
                  AND R.ADRESSID = A.ADRESSID
               );
oder

Code:
UPDATE ADRESSEN A
   SET A.AKTIV = 1
 WHERE A.ADRESSID IN (SELECT ADRESSID
                        FROM RECHNUNGEN R
                       WHERE R.RECHNUNGSNR = 1
                     );

Hat jemand eine Idee wie man das verhindern kann?
Ich sehr nur eine Möglichkeit über Execute Block das funktioniert auch Pfeil schnell:

Code:

EXECUTE BLOCK (IRECHNUNGSNR TYPE OF COLUMN RECHNUNGEN.RECHNUNGSNR = :RECHNUNGSNR)
AS
DECLARE VARIABLE ADRESSID TYPE OF COLUMN ADRESSEN.ADRESSID;
BEGIN
  FOR SELECT ADRESSID
        FROM RECHNUNGEN R
       WHERE R.RECHNUNGSNR = :IRECHNUNGSNR
        INTO :ADRESSID
  DO
  BEGIN
    UPDATE ADRESSEN A
       SET A.AKTIV = 1
     WHERE A.ADRESSID = :ADRESSID;
  END

  SUSPEND;

END

IBExpert 14. Jun 2024 23:23

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
würde helfen zu wissen wie du die tabelle defininert hast und welche indizes existieren
ich vermute mal da sind keine passenden

Uwe Raabe 14. Jun 2024 23:26

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
Zitat:

Zitat von Kostas (Beitrag 1537780)
Allerdings wird in beiden Beispielen die komplette Datenmenge von 500.000 Adressen durchlaufen.

Das ist aber auch nachvollziehbar: Das Exist muss ja für jeden Datensatz ausgewertet werden bevor der akzeptiert oder übersprungen werden kann.

Kostas 15. Jun 2024 12:01

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
ADRESSEN.ADRESSID ist der PK.
RECHNUNGEN.ADRESSID ist ein FK auf ADRESSEN.ADRESSID.
Auf RECHNUNGEN.RECHNUNGSNR ist ein Unique Index gesetzt.

Daran liegt es somit nicht. Ich hätte erwartet, dass der Select auf die Rechnungen durchgeführt wird und die Anzahl der Results gegen den Update gefahren wird. Bei kleinen Datenmengen ist dieses Verhalten auch egal aber bei etwas größeren Datenmengen eben nicht. Im MySQL kann man ein Join für das Update einbauen. In FB geht das leider nicht.

Uwe Raabe 15. Jun 2024 12:12

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
Zitat:

Zitat von Kostas (Beitrag 1537791)
Ich hätte erwartet, dass der Select auf die Rechnungen durchgeführt wird und die Anzahl der Results gegen den Update gefahren wird.

Das mag für dein zweites Code-Beispiel gelten, aber für das mit dem Exists wohl eher nicht.

Was du in dem BLOCK machst, ist ja genau das, was du erwartest. Ein ähnliches Verhalten hätte ich jetzt auch von den zweiten Code-Beispiel erwartet. Da dem offenbar nicht so ist, wäre eine Analyse der in FB verwendeten Strategie interessant. Vielleicht kann man da mit einer PLAN-Anweisung noch was tunen.

himitsu 15. Jun 2024 13:16

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1537786)
Zitat:

Zitat von Kostas (Beitrag 1537780)
Allerdings wird in beiden Beispielen die komplette Datenmenge von 500.000 Adressen durchlaufen.

Das ist aber auch nachvollziehbar: Das Exist muss ja für jeden Datensatz ausgewertet werden bevor der akzeptiert oder übersprungen werden kann.

Na eigentlich würde es ja reichen, wenn beim ersten Fund abgebrochen wird.
Gefunden ist gefunden und noch mehr finden ändert nichts.

exists(...)
vs
count(...) > 0

Ja, beim Count könnte man zwar auch schon beim Ersten abbrechen, aber nicht, wenn Zählen und Vergleich nicht in einer gemeinsamen optimierbaren Operation stattfinden.

count(...) > 3
könnte optimiert ja auch schon beim dritten Fund abbrechen.



Kommt also drauf an, wie das DBMS die Aufgabe löst.
* erst suchen und dann schauen, was/wieviel rauskam
* speziell suchen und dabei gleich auswerten

Uwe Raabe 15. Jun 2024 13:19

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
Zitat:

Zitat von himitsu (Beitrag 1537793)
Na eigentlich würde es ja reichen, wenn beim ersten Fund abgebrochen wird.
Gefunden ist gefunden und noch mehr finden ändert nichts.

Das ist schon richtig - und das wird im SELECT-Teil wohl auch so passieren. Ändert aber nichts daran, dass trotzdem der gesamte Artikelstamm durchsucht und für jeden Datensatz das EXISTS ausgewertet wird.

himitsu 15. Jun 2024 13:24

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
kommt drauf an, wie es optimiert wird
und welche Datenlage wahrscheinlicher geben ist.

* das SubSelect zu Beginn einmal auswerten dann das Exists auf diese TempTable (also mit IN)
* in jedem Durchlauf das Exists+Select neu auswerten (also mit EXISTS)

Das Eine ist besser, wenn sehr viele ADRESSEN und sehr wenige RECHNUNGEN
das Andere ist besser, wenn sehr wenige ADRESSEN und sehr viele RECHNUNGEN (was hier bestimmt wahrscheinlicher sein wird).

Kostas 15. Jun 2024 13:56

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
Rows affected funktioniert bei Execute Block auch nicht oder?

Uwe Raabe 15. Jun 2024 13:59

AW: FB 3.0 Update mit where exists durchläuft alle Record der upd tbl.
 
Könntest du den BLOCK Code nicht als Stored Procedure anlegen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:52 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz