Offenes Webinar "Reihenfolge der Ausführung einer SELECT-Abfrage und eines Abfrageplans in MS SQL Server"

    Hallo nochmal!

    Kolleginnen und Kollegen, am letzten Tag im Januar starten wir den Kurs „MS SQL Server Developer“ , in dessen Rahmen wir eine thematische offene Lektion hatten. Wir sprachen darüber, wie MS SQL Server eine SELECT-Abfrage ausführt, besprachen die Reihenfolge, in der und was analysiert wird, und gingen auch ein wenig in das Lesen des Abfrageplans ein.

    Der Ausbilder ist Kristina Kucherova , Datenmodellarchitektin bei der Sberbank in Russland.


    Ziele und Route des Webinars

    Am Anfang des Webinars wurden folgende Ziele gesetzt:

    1. Sehen Sie, wie der Server die Anfrage ausführt und warum dies so geschieht.
    2. Lernen Sie, den Abfrageplan zu lesen.

    Um dies zu erreichen, hat der Lehrer einen einfachen, aber effektiven Weg vorbereitet:



    Warum brauchen wir einen Abfrageplan?

    Der Abfrageplan ist ein sehr nützliches Werkzeug, das leider viele Entwickler nicht verwenden. Auf den ersten Blick scheint es, dass es nicht notwendig ist, die Mechanik der Abfrage zu kennen. Wenn Sie jedoch wissen, was in SQL Server geschieht, können Sie eine effizientere Abfrage schreiben. Und es wird zum Beispiel bei der Optimierung sehr hilfreich sein.

    Wie sehen wir die SELECT-Abfrage?

    Mal sehen, wie eine SELECT-Abfrage aussieht:

    SELECT [Feld1], [Feld2] ...
    Welche Felder wählen wir aus?
    FROM [Tabelle]
    Von wo aus
    WO [Bedingungen]
    Wo sind die Bedingungen so und so
    GROUP BY [Feld1]
    Gruppieren nach Feldern
    HABEN [Bedingungen]
    Solche und solche Bedingungen haben
    ORDER BY [Feld1]
    Bestellung (sortieren)

    Wie kann ich verstehen, wohin die Daten gehen sollen?

    Der Server versucht zuerst zu verstehen, wann eine Anforderung eingeht, wo die Daten abgelegt werden sollen. Der FROM-Befehl beantwortet diese Frage, da wir hier eine Liste von Tabellen (oder den Namen einer einzelnen Tabelle) haben werden.

    Stellen wir uns zur Verdeutlichung vor, dass unser Server eine Art Butler ist, den wir anordnen, um uns im Urlaub abzuholen. Dementsprechend fängt der Butler an zu denken, und in welchem ​​Schrank befinden sich die notwendigen Dinge (in welcher Tabelle brauchen Sie Daten)? Und damit unser Butler seine Aufgabe problemlos erledigen kann, verwenden wir FROM.



    Wie kann man verstehen, welche Daten zu übernehmen sind?

    Angenommen, der Butler hat den Schrank gefunden, den er brauchte, und öffnete ihn. Aber was nehmen Sie mit? Vielleicht fahren wir in ein Skigebiet? Oder vielleicht an einem heißen sonnigen Strand? Damit unsere Dinge zum Wetter passen, benötigen wir den WHERE-Befehl, der die Bedingungen definiert, das heißt, die Daten filtern kann. Wenn es heiß ist, nehmen wir Schiefer, T-Shirts und Badeanzüge, wenn es kalt ist (Handschuhe, gestrickte Socken, Pullover)).

    Im nächsten Schritt werden diese Daten in Gruppen zusammengefasst. Dies geschieht mit Hilfe von GROUP BY (Hemden separat, Socken separat). Entsprechend den Ergebnissen der Gruppierung können Sie mit HAVING eine weitere Bedingung auferlegen (zum Beispiel, um ungepaarte Dinge auszusondern). Am Ende fügen wir alles mit Hilfe von ORDER BY hinzu, was zu einer vorgefertigten Tasche von Dingen oder einem geordneten Datenblock führt.



    Übrigens gibt es eine Nuance, aber es liegt in der Tatsache, dass es einen Unterschied gibt, welche Bedingungen in WO und welche in HAVING vorgeschrieben werden sollen. Aber das ist besser, das Video anzuschauen.

    Wir machen weiter. Der Pfad der Anfrage wird in Form eines Abfrageplans im Cache gespeichert , das heißt, unser Butler schreibt alles auf, weil er ein guter Butler ist - was ist, wenn Sie Ihre Bestellung nächstes Jahr wiederholen möchten? Und solche Pläne können im Prinzip viele sein.

    Verbindungstypen im Abfrageplan

    Es gibt drei Verbindungen, auf die Sie im Abfrageplan stoßen können:

    1. Verschachtelte Schleife
    2. Join zusammenführen.
    3. Hash beitreten

    Bevor wir uns näher mit ihnen beschäftigen, lassen Sie uns zusammenfassen, warum wir überhaupt den Anforderungsplan lesen sollten. In der Tat ist es sehr nützlich, wie Sie lernen werden:

    • welcher Index verwendet wird;
    • In welcher Reihenfolge wird join gemacht?
    • was aus dem Puffer ausgewählt wird;
    • wie viel ein Server für eine Ressource ausgibt;
    • Was ist der Unterschied zwischen einem hypothetischen und einem echten Plan.

    Verschachtelte Schleife

    Nehmen wir an, wir müssen Daten aus verschiedenen Tabellen verbinden. Lassen Sie uns diese Tabellen in Form von ... einer kleinen Menge von Skittles-Bonbons und voller M & M-Verpackung präsentieren.



    Wenn Sie den Nested Loop-Typ anschließen, nehmen wir die Bonbonskittles und dann erhalten Sie blind die Bonbons aus dem M & M-Paket. Wenn wir nicht auf eine Süßigkeit derselben Farbe stoßen (dies ist unsere Bedingung), erhalten wir die nächste, das heißt eine normale Suche. Daher können wir sagen, dass sich die Nested-Loop-Verbindung eher für kleine Datenmengen eignet. Wenn es viele Daten gibt, ist Busting natürlich nicht die beste Option.



    Mal sehen, wie es im SQL-Panel aussieht:

    --drop table skittles
     --drop table mms
    --запрос для окна слева
    create table mms 
    (id int identity(1,1), 
     color varchar(25),
     taste varchar(15))
     insert into mms (color, taste)
     values ('yellow', 'chocolate')
     insert into mms (color, taste)
     values ('red', 'nuts')
     create clustered index IX_mms_color ON mms(color);
     create table skittles 
    (id int identity(1,1), 
     color varchar(25),
     taste varchar(15))
    create index IX_skittles_id ON skittles(id);
    create clustered index IX_skittles_color ON skittles(color);
    insert into skittles (color, taste)
     values ('red', 'cherry')
     insert into skittles (color, taste)
     values ('blue', 'strange')
    insert into skittles (color, taste)
     values ('yellow', 'lemon')
     insert into skittles (color, taste)
     values ('green', 'apple')
    insert into skittles (color, taste)
     values ('orange', 'orange')
    --запрос для правого окна
     select mms.*
    from mms join skittles on 
      mms.color = skittles.color
       select *
    from mms join skittles on 
      mms.color = skittles.color



    Join verbinden

    Ein Join wird für große Datenmengen verwendet. Wenn Sie eine Zusammenführungsverknüpfung haben, haben beide Tabellen einen Index, über den sie verknüpft werden können. Bei Bonbons ist es so, als wären sie vorher farbig angeordnet.

    Alles sieht so aus:



    --2 tables 50000 rows, only clustered index by color, color is not unique
     select COUNT(*)
    from mms_big join skittles_big on 
      mms_big.color = skittles_big.color



    Merge Join ist in den folgenden Fällen gut:

    • große Datensätze;
    • identische Verbindungsfelder desselben Typs;
    • Es gibt Indizes zu den Verbindungsfeldern.

    Hash-Join

    Hash-Join wird für unsortierte große Datenmengen verwendet. Um die Tabellen in diesem Fall zu verknüpfen, müssen Sie etwas erstellen, das einen Index nachahmt.

    Hash-Join-Beispiel:

    --drop table skittles
     --drop table mms
    --запрос для окна слева
    create table mms 
    (id int identity(1,1), 
     color varchar(25),
     taste varchar(15))
     insert into mms (color, taste)
     values ('yellow', 'chocolate')
     insert into mms (color, taste)
     values ('red', 'nuts')
     insert into mms (color, taste)
     values ('blue', 'strange')
     insert into mms (color, taste)
     values ('green', 'chocolate')
    insert into mms (color, taste)
     values ('orange', 'chocolate')
     create table skittles 
    (id int identity(1,1), 
     color varchar(25),
     taste varchar(15))
    insert into skittles (color, taste)
     values ('red', 'cherry')
     insert into skittles (color, taste)
     values ('blue', 'strange')
    insert into skittles (color, taste)
     values ('yellow', 'lemon')
     insert into skittles (color, taste)
     values ('green', 'apple')
    insert into skittles (color, taste)
     values ('orange', 'orange')
    --запрос для правого окна
     select *
    from mms join skittles on 
      mms.color = skittles.color



    Der Klarheit halber erinnern wir uns an unsere Süßigkeiten: Die



    Hash-Join-Anwendung umfasst zwei Aktionsphasen:

    1. Build - Erstellt eine Hashtabelle unter Verwendung der kleinsten Tabelle. Für jeden Wert in der Tabelle ist 1 ein Hash. Der Wert wird in einer Hashtabelle gespeichert und der berechnete Hashwert wird als Schlüssel verwendet.
    2. Sonde Für jede Zeile aus Tabelle Nr. 2 wird der Hashwert anhand der Felder berechnet, die im Join angegeben sind (operator =). Suchen Sie in der Hashtabelle nach einem Hash, überprüfen Sie die Feldwerte.







    Wenn Hash-Join gut ist:

    • großer Datensatz;
    • kein Rand im Rand.

    Ein wichtiger Punkt: Wenn nicht genügend Speicherplatz vorhanden ist, wird die Aufnahme in Tempdb - auf Platte gespeichert.

    Freunde, außer den oben genannten, enthalten in der offenen Lektion andere interessante Punkte, die am besten gesehen werden können, wenn sie das Video ansehen. Wir bieten an, den Tag der offenen Tür des Kurses „MS SQL Server Developer“ zu besuchen , an dem Sie dem Lehrer alle Fragen stellen können.

    Die Lehrerin Kristina Kucherova, PS-Lehrerin, dankt Jes Schultz Borland für ihre Präsentation mit den PASS Summitt Execution Plans, die zur Vorbereitung der offenen Lektion verwendet wurden.

    Jetzt auch beliebt: