AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Firebird - where Bedingung mit Bedingung
Thema durchsuchen
Ansicht
Themen-Optionen

Firebird - where Bedingung mit Bedingung

Ein Thema von lxo · begonnen am 3. Sep 2024 · letzter Beitrag vom 4. Sep 2024
Antwort Antwort
Seite 2 von 2     12   
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#11

AW: Firebird - where Bedingung mit Bedingung

  Alt 3. Sep 2024, 21:38
Mein Gedanke war aber wenn die zweite Bedingung eh schon false ist, wozu wird da noch was gelesen. Die könnte er ja eigentlich ignorieren.
Macht der ja auch wenn ich iif mache, aber nur mit konstanten Werten.
Das könnte in Deiner Vermutung könnte aber genau der Knackpunkt sein.

Delphi hat 'nen Kompilerschalter mit dem man die vollständige Auswertung von boolschen Vergleichen ein- oder ausschalten kann. Hat Firebird auch die Fähigkeit bei der Auswertung eines Teiles einer Bedingung zu erkennen, dass sie nur noch nicht erfüllt sein kann und es daher die weitere Arbeit unterlassen kann?

Sieht bei Deinem Beispiel eher nicht so aus.
  Mit Zitat antworten Zitat
lxo

Registriert seit: 30. Nov 2017
288 Beiträge
 
Delphi 12 Athens
 
#12

AW: Firebird - where Bedingung mit Bedingung

  Alt 3. Sep 2024, 22:06
Schade schade, könnte so eine schöne Lösung werden ohne alles in Delphi anpassen zu müssen.
Dann muss ich mal weiter überlegen was man machen kann.
Ich könnte mir vorstellen das man es mit einem angepassten PLAN und IIF hinbekommt. Da klappt es ja mit konstanten Werten wie gewünscht nur mit Feldern nicht. Aber krieg es nicht so hingebogen wie gewünscht.
Falls jemand noch weitere Tipps oder Ideen hat, gerne her damit.
  Mit Zitat antworten Zitat
lxo

Registriert seit: 30. Nov 2017
288 Beiträge
 
Delphi 12 Athens
 
#13

AW: Firebird - where Bedingung mit Bedingung

  Alt 4. Sep 2024, 10:04
Ginge sowas?
SQL-Code:
select * from tabelle where id = ((:condition and (id = 1))
union all
select * from tabelle where id = (not :condition and (id = 20))
Ich hab meine optimale Lösung mit UNION hinbekommen, mit der nur die erforderlichen Reads gemacht werden.
Danke für den Hinweis mit UNION, hatte das irgendwie außer acht gelassen da ich irgendwie davon ausgegangen bin das es mit dem UNION noch umständlicher für Firebird wäre.

Code:
select T1.ID as T1_ID,
       T2.ID as T2_ID,
       T3.WERT
from TABELLE1 T1
cross join TABELLE2 T2
inner join TABELLE3 T3 on T3.T1_ID = T1.ID and
                T1."GLOBAL" and
            T3.T2_ID = ( select T2_TEMP.ID
                      from TABELLE2 T2_TEMP
                             where T2_TEMP.MAIN)            
union
select T1.ID as T1_ID,
       T3.T2_ID,
       T3.WERT
from TABELLE1 T1
inner join TABELLE3 T3 on T3.T1_ID = T1.ID and
      not T1."GLOBAL"
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#14

AW: Firebird - where Bedingung mit Bedingung

  Alt 4. Sep 2024, 13:59
Nimm bitte mal nur die zweite Hälfte des Union und schau, ob sich hierdurch was verbessert / verändert:
SQL-Code:
select T1.ID as T1_ID,
       T3.T2_ID,
       T3.WERT
from
(
  select ID from TABELLE1 where not "GLOBAL"
) T1
inner join TABELLE3 T3 on T3.T1_ID = T1.ID
In der ersten Hälfte des Union lässt sich bestimmt auch noch was optimieren, weiß aber gerade keinen sinnvollen Ansatz dazu.
SQL-Code:
select T1.ID as T1_ID,
       T2.ID as T2_ID,
       T3.WERT
from TABELLE1 T1
cross join TABELLE2 T2
inner join TABELLE3 T3 on T3.T1_ID = T1.ID and
                T1."GLOBAL" and
            T3.T2_ID = ( select T2_TEMP.ID -- sowas ist nicht unbedingt performant
                      from TABELLE2 T2_TEMP
                             where T2_TEMP.MAIN)
Leider ist es nicht unbedingt einfach die SQL-Syntax zu prüfen, wenn man keine entsprechenden Tabellen und Daten hat, daher ein Versuch für die erste Hälfte des Union als Idee, ohne Anspruch auf korrekte Syntax:
SQL-Code:
select T1.ID as T1_ID,
       T2.ID as T2_ID,
       T3.WERT
from
(
  select ID from TABELLE1 where "GLOBAL"
) T1
cross join TABELLE2 T2
inner join TABELLE3 T3 on T3.T1_ID = T1.ID
inner join (select ID from TABELLE2 where MAIN) T4 on T3.T2_ID = T4.ID
Wenn das funktionieren sollte, ergäbe sich daraus folgendes SQL:
SQL-Code:
select T1.ID as T1_ID,
       T2.ID as T2_ID,
       T3.WERT
from
(
  select ID from TABELLE1 where "GLOBAL"
) T1
cross join TABELLE2 T2
inner join TABELLE3 T3 on T3.T1_ID = T1.ID
inner join (select ID from TABELLE2 where MAIN) T4 on T3.T2_ID = T4.ID
union
select T1.ID as T1_ID,
       T3.T2_ID,
       T3.WERT
from
(
  select ID from TABELLE1 where not "GLOBAL"
) T1
inner join TABELLE3 T3 on T3.T1_ID = T1.ID
Kann es passieren, dass Datensätze sowohl in der ersten Hälfte des Union selektiert werden, als auch in der zweiten Hälfte des Union? Wenn nein, ändere das Union bitte in Union All. Dadurch muss die Datenbank das Ergebnis nicht sortieren und von Dubletten bereinigen, was die Abfrage (je nach Datenmenge) durchaus deutlich beschleunigen kann.
  Mit Zitat antworten Zitat
lxo

Registriert seit: 30. Nov 2017
288 Beiträge
 
Delphi 12 Athens
 
#15

AW: Firebird - where Bedingung mit Bedingung

  Alt 4. Sep 2024, 15:54
Nimm bitte mal nur die zweite Hälfte des Union und schau, ob sich hierdurch was verbessert / verändert:
SQL-Code:
select T1.ID as T1_ID,
       T3.T2_ID,
       T3.WERT
from
(
  select ID from TABELLE1 where not "GLOBAL"
) T1
inner join TABELLE3 T3 on T3.T1_ID = T1.ID
In der ersten Hälfte des Union lässt sich bestimmt auch noch was optimieren, weiß aber gerade keinen sinnvollen Ansatz dazu.
SQL-Code:
select T1.ID as T1_ID,
       T2.ID as T2_ID,
       T3.WERT
from TABELLE1 T1
cross join TABELLE2 T2
inner join TABELLE3 T3 on T3.T1_ID = T1.ID and
                T1."GLOBAL" and
            T3.T2_ID = ( select T2_TEMP.ID -- sowas ist nicht unbedingt performant
                      from TABELLE2 T2_TEMP
                             where T2_TEMP.MAIN)
Leider ist es nicht unbedingt einfach die SQL-Syntax zu prüfen, wenn man keine entsprechenden Tabellen und Daten hat, daher ein Versuch für die erste Hälfte des Union als Idee, ohne Anspruch auf korrekte Syntax:
SQL-Code:
select T1.ID as T1_ID,
       T2.ID as T2_ID,
       T3.WERT
from
(
  select ID from TABELLE1 where "GLOBAL"
) T1
cross join TABELLE2 T2
inner join TABELLE3 T3 on T3.T1_ID = T1.ID
inner join (select ID from TABELLE2 where MAIN) T4 on T3.T2_ID = T4.ID
Wenn das funktionieren sollte, ergäbe sich daraus folgendes SQL:
SQL-Code:
select T1.ID as T1_ID,
       T2.ID as T2_ID,
       T3.WERT
from
(
  select ID from TABELLE1 where "GLOBAL"
) T1
cross join TABELLE2 T2
inner join TABELLE3 T3 on T3.T1_ID = T1.ID
inner join (select ID from TABELLE2 where MAIN) T4 on T3.T2_ID = T4.ID
union
select T1.ID as T1_ID,
       T3.T2_ID,
       T3.WERT
from
(
  select ID from TABELLE1 where not "GLOBAL"
) T1
inner join TABELLE3 T3 on T3.T1_ID = T1.ID
Kann es passieren, dass Datensätze sowohl in der ersten Hälfte des Union selektiert werden, als auch in der zweiten Hälfte des Union? Wenn nein, ändere das Union bitte in Union All. Dadurch muss die Datenbank das Ergebnis nicht sortieren und von Dubletten bereinigen, was die Abfrage (je nach Datenmenge) durchaus deutlich beschleunigen kann.

1) Macht keinen Unterschied, Anzahl der reads und Ausführungszeit ist die selbe.

2) Hatte ich auch gedacht, aber Firebird macht das schon auf irgendeine weise effizient.
Habe auf die Tabelle2 durch den Subselect nur ein zusätzliches reads, egal wieviele Datensätze ich habe.

3) Das macht es langsamer, deutlich mehr Zugriffe auf Tabelle3 dadurch.

4) UNION ALL hat nochmal die Ausführungszeit verbessert. Besonders bei vielen Datensätzen merkbar. (Danke für den Tipp )
Mithilfe von UNION ALL ist der SQL schon so gut wie so schnell wie der direkte Zugriff auf Tabelle3.

Direkter Zugriff auf die original Tabelle3 mit ca. 3.800.000 Datensätzen: Select * from Tabelle3 (fetch all) = (Durchschnittszeit bei 10x ausführen 12s 875ms)
Mit meiner View (Durchschnittszeit bei 10x ausführen 13s 050ms)

Wenn ich als Bedingung die T2_ID mitgebe ist der unterschied zwischen original Tabelle und View eigentlich gar nicht mehr festzustellen von der Zeit.

Geändert von lxo ( 4. Sep 2024 um 16:09 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz