![]() |
AW: SQL Script optimieren damit es schneller geht
Zitat:
|
AW: SQL Script optimieren damit es schneller geht
Ich zeige Euch mal wie die Daten in den Tabellen aussehen können. Eventuell wird es dann deutlicher wo mein Fehler leigt.
Also als erstes einmal bei dem Status N kann es keine Zeile in Tabelle2 geben. Es kann auch keine Zeile in Tabelle 2 geben bei dem der Wert des Feldes Status NULL ist. Es liegt ein Index auf den Felder CoNummer und Status der Teabelle1 sowie CoNummer und Status der Tabelle2
Delphi-Quellcode:
Als Ergebnis möchte ich nun haben 1,3,4 und 6. Also alle Datensätze aus Tabelle1 wo kein Datensatz in Tabelle 2 vorhanden ist.
Tabelle1
Masternummer CoNummer Status 1 2514 N 2 2515 Start 3 2516 Warten 4 2517 Produktion 5 2518 Ausgabe 6 2519 Komplett Tabelle2 CoNummer Status 2515 Start 2516 Start 2517 Start 2517 Warten 2518 Start 2518 Warten 2518 Produktion 2518 Ausgabe |
AW: SQL Script optimieren damit es schneller geht
IMHO ist hier nicht viel zu machen.
Für die Verknüpfung mit Tabelle 2 hilft dir kein Index. Fakt ist: Die Indexe greifen nur auf Status und Storno, alle anderen Datensätze von Tabelle 1 werden beim Select "angefasst". Du kannst nur noch sicherstellen, das zur Prüfung auch nur ein Datensatz in Tabelle 2 "angefasst" wird, indem du statt einem Join exists verwendest. Wenn es schnell sein soll, benötigst du IMHO ein zusätzliches indexiertes Feld in Tabelle 1, welches über "after insert update delete" Trigger der Tabelle 2 aktuell gehalten wird. Frank |
AW: SQL Script optimieren damit es schneller geht
Ich bin neugierig, aber leider erfahrungslos mit Firebird. Im Prinzip würde das hier das Ergebnis liefern, oder?
Code:
SELECT * FROM Tabelle1
WHERE NOT EXISTS ( SELECT CoNummer FROM Tabelle2 WHERE Tabelle2.CoNummer = Tabelle1.CoNummer ) |
AW: SQL Script optimieren damit es schneller geht
Zitat:
Will ich nur wissen, ob es etwas gibt oder nicht, dann frage ich mit Exists ab: Beispiele:
SQL-Code:
Das war nach meiner bisherigen Erfahrung immer die schnellste Variante für eine Existenz- bzw. Nichtexistenzprüfung.
/* gibt es da was in Tabelle2 zu Tabelle1? */
select benötigtespalte(n) from tabelle1 where exists (select 1 from tabelle2 where tabelle1.schlüssel = tabelle2.schlüssel) /* gibt es nichts in Tabelle 2 zu Tabelle 1? */ select benötigtespalte(n) from tabelle1 where not exists (select 1 from tabelle2 where tabelle1.schlüssel = tabelle2.schlüssel) Brauche ich sowas nur für kleine Teilmengen der betroffenen Tabellen dann wird daraus sinngemäß:
SQL-Code:
Ja, ich weiß, das wird zuweilen sehr schwer lesbar, aber wenn's hilft, dann ist dem so. Im Zweifelsfalle erstellt man sich für die "innern Selects" halt Views, dann ist der Zugriff wieder wie im ersten Beispiel leicht lesbar, ohne das Laufzeitveränderungen auftreten.
select * from (
select benötigtespalte(n) from tabelle1 where EinschränkendeBedingungen zu Tabelle1 ) a where exists /* Wenns was geben soll */ ( select Schlüsselspalten from ( select Schlüsselspalten from tabelle2 where EinschränkendeBedingungen zu Tabelle2 ) b ) where a.schlüssel = b.schlüssel Zitat:
Meine Erfahrung hat mich jedoch gelehrt, dass der Optimizer hier bei starken Einschränkungen der Daten auf Teilmengen, die dann zu verknüpfen sind, häufig "daneben liegt". Er kann bei der Optimierung (vermutlich) die aus den Einschränkungen resultierenden Teilmengen nicht optimal einschätzen, um den laufzeittechnisch und dateninduziert optimalen Plan zu erstellen. Würde dashier (sinngemäß) den Anforderungen entsprechen?
SQL-Code:
Und ist es auch akzeptabel schnell?
select a.Masternummer from
( select Masternummer from tabelle1 where status <> 'N' and status is not null ) a where not exists ( select 1 from tabelle2 b where a.CoNummer = b.CoNummer ) |
AW: SQL Script optimieren damit es schneller geht
Zitat:
SQL-Code:
Ist meist etwas schneller, kommt aber wohl vor allem auf die konkreten Daten (und die DB) an.
select *
from t1 left join t2 on (t1.id=t2id) where t2.id is null Man sollte immer beide Wege probieren. Gruß K-H |
AW: SQL Script optimieren damit es schneller geht
Zitat:
Im Zweifel gilt bei mir immer: Ausprobieren, bis die (hoffentlich) beste Lösung gefunden wurde. "Die beste Lösung" gibt es nicht. |
AW: SQL Script optimieren damit es schneller geht
In Firebird kann man sich doch bestimmt auch den EXPLAIN PLAN/ANALYSE ausgeben lassen und sieht ob und welcher Index verwendet wird.
Mal probiert den JOIN umzudrehen? Im Beispiel hat Tabelle2 mehr Einträge.
Delphi-Quellcode:
> für jeden Eintrag in Tabelle 1 alle vielen Einträge in Tabelle 2 durchsuchen (NULL steht nicht im Index, also FullScan und Index ignoriert)
FROM Tabelle1 JOIN Tabelle2
Delphi-Quellcode:
> für jeden Eintrag in Tabelle 2 die wenigen Einträge in Tabelle 2 durchsuchen
FROM Tabelle2 JOIN Tabelle1
Oder halt die Variante ohne JOIN.
SQL-Code:
Das SubSelect kann nun einen Index gut ausnutzen, wenn der über CoNummer+Status geht.
SELECT *
FROM Tabelle1 WHERE NOT exists( SELECT true FROM Tabelle2 WHERE Tabelle1.CoNummer = Tabelle2.CoNummer AND Tabelle1.Status = Tabelle2.Status LIMIT 1 ) Keine Ahnung, ob EXISTS schon so schlau ist und die Felder (hier nur ein True) ignoriert, weil sie niemals genutzt werden, und bereits ein LIMIT verwendet, da ja schon ab dem ersten Fund das Ergebnis feststeht. |
AW: SQL Script optimieren damit es schneller geht
Zitat:
|
AW: SQL Script optimieren damit es schneller geht
Würde das in etwa so übersetzen:
Statt
SQL-Code:
könnte dashier gehen:
SELECT *
FROM Tabelle1 WHERE NOT exists( SELECT true FROM Tabelle2 WHERE Tabelle1.CoNummer = Tabelle2.CoNummer AND Tabelle1.Status = Tabelle2.Status LIMIT 1 )
SQL-Code:
Syntaktisch geht das so unter FireBird (grade mal ausprobiert), ob's auch sinnvolle Ergebnisse liefert, kann ich nicht sagen, first 1 1 sieht jedenfalls seltsam aus ;-)
SELECT *
FROM Tabelle1 WHERE NOT exists( SELECT first 1 1 FROM Tabelle2 WHERE Tabelle1.CoNummer = Tabelle2.CoNummer AND Tabelle1.Status = Tabelle2.Status ) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:01 Uhr. |
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