Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

1 Vergleich = 1 Sekunden, 2 Vergleiche = 2 Minuten

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von knabnetaD, 29 Oktober 2012.

  1. knabnetaD

    knabnetaD Benutzer

    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!
     
  2. ukulele

    ukulele Datenbank-Guru

    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?
     
  3. knabnetaD

    knabnetaD Benutzer

    Ja das Ergebnis von Abfrage 1 und 2 ist das Ergebnis der Abfrage 3.
    Clustered Index liegt jeweils auf der id-Spalte.
     
  4. Tommi

    Tommi Datenbank-Guru

    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
     
  5. ukulele

    ukulele Datenbank-Guru

    Gute Idee, aber sollte es sich bei ID um einen Uniqueidentifier handelt wird das nicht gehen.
     
  6. Tommi

    Tommi Datenbank-Guru

    Hallo,

    wenn die ID ein Uniqueidentifier wäre, würde auch der "größer als" Vergleich nicht funktionieren.
     
  7. knabnetaD

    knabnetaD Benutzer

    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!
     
  8. Tommi

    Tommi Datenbank-Guru

    Hi,

    möchtest du noch eine Erklärung oder reicht dir, dass es läuft ?

    VG Tommi
     
  9. ukulele

    ukulele Datenbank-Guru

    Ich möchte eine Erklärung wenn du eine hast :)
     
  10. Tommi

    Tommi Datenbank-Guru

    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
     
    Walter gefällt das.
  11. knabnetaD

    knabnetaD Benutzer

    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.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden