1 Vergleich = 1 Sekunden, 2 Vergleiche = 2 Minuten

knabnetaD

Benutzer
Beiträge
12
Hallo Leute,
ich habe eine Frage zu folgenden Querys:

Die Query
Code:
select id, data
from table1
where
    exists (select id
            from table2
            where table2.id = table1.id
    and table1.id > (SELECT TOP 1 id
                                            FROM table3
                                            order by id desc
                                            )
braucht 1-2 sekunden um mir das Ergebnis zu liefern.

Diese Query
Code:
select id, data
from table1
where
    exists (select id
            from table2
            where table2.id = table1.id
    and table1.id > (SELECT TOP 1 id
                                            FROM table4
                                            order by id desc
                                            )
braucht auch 1-2 sekunden um mir das ergebnis zu liefern.

Aber warum braucht diese Query dann 1-2Minuten um das Erbgenis zu liefern?
Code:
select id, data
from table1
where
    exists (select id
            from table2
            where table2.id = table1.id
    and (table1.id > (SELECT TOP 1 id
                                            FROM table3
                                            order by id desc
                                            )
    or table1.id > (SELECT TOP 1 id
                                            FROM table4
                                            order by id desc
                                            )
                )
Da stimmt doch was nicht, oder?

Ich hoffe ihr könnt mir helfen.
DANKE!
 
Werbung:
Ich vermute mal die ersten beiden Abfragen ergeben zusammen auch das Ergebnis der 2ten?

Leider keine Idee, ich sehe da auch kein Problem. Hast du Indexe in Verwendung?
 
Hi,

mit deinen Unterabfragen und der DESC-Sortierung ermittelst du ja nichts anderes als die maximale ID in der Tabelle.
Dann benutz diese Funktion doch auch, das sollte es etwas schneller machen. Eine Sortierung benötigt immer Zeit!

Viele Grüße,
Tommi
 
oh man, warum einfach wenns auch kompliziert geht -.-
an max() hab ich garnet gedacht.
so läufts die query jetzt auch in 1-2 sekunden ab.

ich finds trotzdem komisch das die 2 "select top 1"-querys isoliert eine sekunde und kombiniert ne minute brauchen.

naja wayne jetzt läufts ja^^

vielen dank!
 
ja, die habe ich tatsächlich.

Zunächst muss man beachten, dass der SQL Server die Sub-Selects parallel ausführt und dann erst eine Zusammenführung macht. (Merge Join)
Je nach Verknüpfungs bzw. Vergleichs-Kriterium benötigt dieses Merge bereits einiges an Zeit. (Hier die OR-Bedingung zwischen den Sub-Selects)

Die meiste Zeit benötigt die Umsortierung der ID in den Sub-Selects. Das frißt unglaublich viel Zeit.
In den Sub-Selects werden ja alle IDs in umgekehrter Reihenfolge Sortiert, bevor dann der erste Datensatz der Abfrage zur Weiterverarbeitung herangezogen wird.
Wird diese Abfrage allein ausgeführt, funktioniert das noch recht schnell, aber in Zusammenwirken mit der OR-Verknüpfung von zwei Sub-Selects ist das eine echt schön programmierte Bremse ;).

Hier würde es zwar einiges bringen, wenn man auf die ID einen Index mit absteigender Sortierung einführt, aber wenn man sich die Abfrage(Sub-Select) halt genau ansieht erkennt man,
das hier logisch die maximale ID in einer Tabelle ermittelt werden soll (habe ich ja auch schon erkannt).

Also: in Sub-Selects besser keine Sortierung vornehmen - dass braucht gerne mal lange.

Der SQL-Server ermittelt intern einen Ablaufplan für die Abfrage. Bei einer zweiten Ausführung der selben Abfrage sollte diese in der Regel dann sogar etwas schneller ausgeführt werden als beim ersten Mal. Je nachdem kann es hier sogar schon mal helfen, wenn man Abfragekriterien einfach "umdreht". Machmal kann der SQL Server nämlich die günstigste Abfrage-Reihenfolge nicht selber erkennen, dann muss man ihm ein wenig bei der Bedingungs-Abfrage und -Sortierung unter die Arme greifen.

Generell hilft hier bei Performance-Problemen aber erst einmal ein Blick auf das Ablaufdiagramm der Abfrage.

Viele Grüße,
Tommi
 
Werbung:
die lösung mit max() setzt natürlich voraus, dass die id's aufsteigend vergeben werden.
da das aber der fall ist, passt das so.
die erklärung klingt auch einleuchtend.
 
Zurück
Oben