![]() |
AW: in-Klausel in großen Tabellen
Aber muss nicht bei der Distinct + Join Variante der Distinct nur 1x gemacht werden, während beid er exists Variante für jeden Datensatz ein Subselect gemacht werden muss?
|
AW: in-Klausel in großen Tabellen
Ich mag auch mal ;-)
Delphi-Quellcode:
select
A.AuftragsNr , A.Arbeitsgang from Auftrag A join ( select * from ( select Sub.AuftragsNr , count(Sub.Arbeitsgang) Anzahl from Auftrag Sub where (Sub.FertigDatum between 'ANFANG' and 'ENDE') group by Sub.AuftragsNr ) AufAnz where (0 < AufAnz.Anzahl) ) OnlyNotZero on (OnlyNotZero.AuftragsNr = A.AuftragsNr) |
AW: in-Klausel in großen Tabellen
Zitat:
Gruß K-H |
AW: in-Klausel in großen Tabellen
Zitat:
Dort ist eine recht gute Erklärung zu finden: ![]() Zitat:
Unter Oracle war es zu Zeiten, als ich mich damit noch beruflich befasste, deutlich schneller, mit Exists zu arbeiten. Spätestens, wenn die Datenbank den temporary tablespace nutzen musste, konnte man da Unterschiede bemerken, weil irgendwann die Auslagerung des Speichers auf die Festplatte(n) sich im Laufzeitverhalten deutlich bemerkbar machte. Hier im konkreten Fall müssen wir nur wissen, ob es zu 'nem Auftrag mindestens einen Satz im gewünschten Jahr gibt, um dann alle Datensätze zu der Auftragsnummer auszugeben. Mit Exists erhalten wir nur ein Ja oder ein Nein, bei 'nem Join erhalten wir alle Datensätze aus dem gewünschten Jahr. Die werden dann (erstmal) mit allen Datensätzen der Auftragsnummer verbunden. Es kann also (auf Auftragsnummerebene) einen CROSS JOIN geben. (DeddyHs diesbezügliche Anmerkung ist daher angebracht.) Bei einem Join muss man also auch noch sicherstellen, dass keine (partiziellen) Dubletten entstehen. Das ist aufwändiger, als eine "simple" Existenzprüfung. Daher ist (meiner Meinung nach) im vorliegenden Fall Exists vorzuziehen. |
AW: in-Klausel in großen Tabellen
Zitat:
Code:
Ich hatte allerdings auch schon Fälle, wo es nicht anders ging als ein Zwischenergebnis in einer temporären Tabelle zu speichern. In deinem Fall würde man da
select distinct <feldliste> from tabelle
where exists ( select AuftragNr from Tabelle where Year(FertigDatum) = 2018) order by auftragnr, arbeitsgang das Resultat von
Code:
ablegen. Diese Query gibt halt deutlich weniger Zeilen zurück als ohne "distinct", ist aber aufwendiger in der Verarbeitung.
select distinct AuftragNr from Tabelle where Year(FertigDatum) = 2018)
|
AW: in-Klausel in großen Tabellen
Also ich würde folgendes tun:
1. Ein Feld "Jahr" einführen und entsprechend füllen 2. Einen Index für das Feld "Jahr" anlegen 3. Anschließend folgende Abfrage ausprobieren:
Code:
4. Falls das nicht performant ist, dann das Ergebnis der inneren Abfrage vorher in einer (temporären) Tabelle zwischenspeichern (in dieser Tabelle den Index auf AuftragNr nicht vergessen!) und dann die obengenannte Abfrage auf die temporäre Tabelle machen. Das würde dann ungefähr so aussehen:
SELECT * FROM tabelle a
INNER JOIN ( SELECT DISTINCT AuftragNr FROM Tabelle where Jahr = 2018) i ON a.AuftragNr = i.AuftragNr ORDER BY auftragnr, arbeitsgang
Code:
Wenn diese Statements zusammen nicht innerhalb eines Fingeschnippsens durch sind, fresse ich einen Besen... :lol:
CREATE TEMPORARY TABLE `temptable` (
`AuftragNr` int(11), PRIMARY KEY (`AuftragNr`) ) ENGINE=InnoDB; INSERT INTO `temptable` SELECT DISTINCT AuftragNr FROM Tabelle where Jahr = 2018; SELECT * FROM `tabelle` a INNER JOIN `temptable` i ON a.AuftragNr = i.AuftragNr ORDER BY AuftragNr, arbeitsgang; DROP TEMPORARY TABLE `temptable`; PS1: Ich habe nicht alle vorherigen Antworten komplett durchgelesen, vielleicht wiederhole ich auch nur bereits Gesagtes. PS2: Ich habe die Statements nicht ausprobiert. |
AW: in-Klausel in großen Tabellen
PS: Ich gehe doch mal davon aus, dass der Themenersteller in seiner Tabelle auf jeden Fall einen Index auf `AuftragsNr` hat...
|
AW: in-Klausel in großen Tabellen
Die Auftragsnummer wird über
SQL-Code:
gebildet. Sie ist ein Konstrukt mehrerer Werte, die zusammen zu einem gewünschten Jahr existieren müssen. Ist diese Existenz gegeben, müssen alle Sätze, die über dieses Konstrukt verfügen, von der Datenbank herausgesucht werden.
concat(waaunr,'-', waaupo)
|
AW: in-Klausel in großen Tabellen
Zitat:
|
AW: in-Klausel in großen Tabellen
Das ist nur dann nicht performant, wenn man für die Abfrage zuerst die beiden Felder zusammenfasst und diese Zusammenfassung für die Wherebedingung nutzt. Da man die Wherebedingung aber über die beiden Felder separat machen kann, sollte das durchaus schnell mit einer Exists-Prüfung im SQL zu realisieren sein. Klar, der Index muss auf diese Abfrage optimiert sein, dass sollte aber mit 'ner modernen Datenbank im Rahmen des Möglichen sein.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:44 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-2025 by Thomas Breitkreuz