sqlschool.gr logo

articles

Articles of SQLschool.gr Team

Outputting SQL Server’s algebrizer bound logical tree

Fivi Panopoulou - Sotiris Karras
Thursday 01 December 2016

Μέρος του Database Engine στον SQL Server είναι και ο Algebrizer ο οποίος είναι υπεύθυνος για την παραγωγή ενός logical tree το οποίο θα δώσει στον Query Optimizer ώστε αυτός με την σειρά του να ξεκινήσει την εύρεση ενός βέλτιστου πλάνου εκτέλεσης για αυτό το query.

Για να παράγει το logical tree, ο Algebrizer εκτελεί διαδικασίες όπως το resolution πιθανών alias σε objects της βάσης, bind των ονομάτων στα objects, aggregate binding καθώς και resolution των datatypes των expression που εμφανίζονται στο query.

Τα διάφορα στάδια για την παραγωγή του παραπάνω logical tree μπορεί κανείς να τα δει χρησιμοποιώντας το undocumented trace flag 8606.

Ας δούμε ένα παράδειγμα από την WideWorldImporters database.


-- Enable output for undocumented trace flag output
DBCC TRACEON(3604)WITH NO_INFOMSGS;
GO

SELECT Ord.PurchaseOrderID, Ord.OrderDate, Ord.IsOrderFinalized, OrdDet.Description
FROM Purchasing.PurchaseOrders AS Ord
INNER JOIN Purchasing.PurchaseOrderLines As OrdDet
    ON Ord.PurchaseOrderID = OrdDet.PurchaseOrderID
WHERE Ord.OrderDate BETWEEN '20100101' AND '20150101'
OPTION (RECOMPILE, QUERYTRACEON 8606);

DBCC TRACEOFF(3604)WITH NO_INFOMSGS;
GO

Από το output (το οποίο το δίνουμε στο τέλος του post) μπορούμε να δούμε ότι το αποτέλεσμα είναι παρόμοιο με την ανάλυση του query σε σχεσιακή άλγεβρα. Πιο συγκεκριμένα αν παρατηρήσουμε το input tree:


*** Input Tree: ***
        LogOp_Project QCOL: [Ord].PurchaseOrderID QCOL: [Ord].OrderDate QCOL: [Ord].IsOrderFinalized QCOL: [OrdDet].Description

            LogOp_Select

                LogOp_Join

                    LogOp_Get TBL: Purchasing.PurchaseOrders(alias TBL: Ord) Purchasing.PurchaseOrders TableID=1026102696 TableReferenceID=0 IsRow: COL: IsBaseRow1000 
	
                    LogOp_Get TBL: Purchasing.PurchaseOrderLines(alias TBL: OrdDet) Purchasing.PurchaseOrderLines TableID=1554104577 TableReferenceID=0 IsRow: COL: IsBaseRow1001 

                    ScaOp_Const TI(bit,ML=1) XVAR(bit,Not Owned,Value=1)

                ScaOp_Logical x_lopAnd

                    ScaOp_Comp x_cmpEq

                        ScaOp_Identifier QCOL: [Ord].PurchaseOrderID

                        ScaOp_Identifier QCOL: [OrdDet].PurchaseOrderID

                    ScaOp_Comp x_cmpGe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(733772))

                    ScaOp_Comp x_cmpLe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(735598))

            AncOp_PrjList 

Στο πρώτο node του δέντρου έχουμε ένα relation project το οποίο θα μας φέρει τις 3 στήλες που έχουμε ορίσει στο SELECT clause του query. Στην συνέχεια για να μας επιστραφούν τα rows, έχουμε ένα relational SELECT operator (LogOp_Select) μέσα στον οποίο θα εκτελεστούν τα operation τα οποία θα μας φιλτράρουν τις εγγραφές που θα επστραφούν. Στην αρχή, έχουμε το LogOp_Join και μέσα του δύο LogOp_Get operators ένα για κάθε πίνακα που συμμετέχει στο join (μαζί με τα TableIDs) καθώς και το join predicate με ScaOp_Comp x_cmpEq και τις δύο στήλες που συμμετέχουν σε αυτό. Στην συνέχεια ένας ScaOp_Loogical x_lopAnd operator περιέχει ένα greater equal και ένα lesser equal operator πάνω στα δύο date constants που δώσαμε στο BETWEEN του WHERE clause.

Το συγκεκριμένο κομμάτι του output του Αlgebrizer θα μπορούσαμε να το πάρουμε και με την χρήση του trace flag 8605, ενώ με την χρήση του 8606 μας επιστρέφεται το συνολικό αποτέλεσμα της διαδικασίας του υπολογισμού του bound logical tree.

Στην συνέχεια, φαίνεται το συνολικό output μετά την χρήση του trace flag.


*** Simplified Tree: ***
        LogOp_Join

            LogOp_Select

                LogOp_Get TBL: Purchasing.PurchaseOrders(alias TBL: Ord) Purchasing.PurchaseOrders TableID=1026102696 TableReferenceID=0 IsRow: COL: IsBaseRow1000 

                ScaOp_Logical x_lopAnd

                    ScaOp_Comp x_cmpGe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(733772))

                    ScaOp_Comp x_cmpLe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(735598))

            LogOp_Get TBL: Purchasing.PurchaseOrderLines(alias TBL: OrdDet) Purchasing.PurchaseOrderLines TableID=1554104577 TableReferenceID=0 IsRow: COL: IsBaseRow1001 

            ScaOp_Comp x_cmpEq

                ScaOp_Identifier QCOL: [OrdDet].PurchaseOrderID

                ScaOp_Identifier QCOL: [Ord].PurchaseOrderID

*******************

*** Join-collapsed Tree: ***
        LogOp_Join

            LogOp_Select

                LogOp_Get TBL: Purchasing.PurchaseOrders(alias TBL: Ord) Purchasing.PurchaseOrders TableID=1026102696 TableReferenceID=0 IsRow: COL: IsBaseRow1000 

                ScaOp_Logical x_lopAnd

                    ScaOp_Comp x_cmpGe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(733772))

                    ScaOp_Comp x_cmpLe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(735598))

            LogOp_Get TBL: Purchasing.PurchaseOrderLines(alias TBL: OrdDet) Purchasing.PurchaseOrderLines TableID=1554104577 TableReferenceID=0 IsRow: COL: IsBaseRow1001 

            ScaOp_Comp x_cmpEq

                ScaOp_Identifier QCOL: [OrdDet].PurchaseOrderID

                ScaOp_Identifier QCOL: [Ord].PurchaseOrderID

*******************
*** Tree Before Project Normalization ***
        LogOp_Join

            LogOp_Select

                LogOp_Get TBL: Purchasing.PurchaseOrders(alias TBL: Ord) Purchasing.PurchaseOrders TableID=1026102696 TableReferenceID=0 IsRow: COL: IsBaseRow1000 

                ScaOp_Logical x_lopAnd

                    ScaOp_Comp x_cmpGe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(733772))

                    ScaOp_Comp x_cmpLe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(735598))

            LogOp_Get TBL: Purchasing.PurchaseOrderLines(alias TBL: OrdDet) Purchasing.PurchaseOrderLines TableID=1554104577 TableReferenceID=0 IsRow: COL: IsBaseRow1001 

            ScaOp_Comp x_cmpEq

                ScaOp_Identifier QCOL: [OrdDet].PurchaseOrderID

                ScaOp_Identifier QCOL: [Ord].PurchaseOrderID

*****************************************
*** Tree After Project Normalization ***
        LogOp_Join

            LogOp_Select

                LogOp_Get TBL: Purchasing.PurchaseOrders(alias TBL: Ord) Purchasing.PurchaseOrders TableID=1026102696 TableReferenceID=0 IsRow: COL: IsBaseRow1000 

                ScaOp_Logical x_lopAnd

                    ScaOp_Comp x_cmpGe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(733772))

                    ScaOp_Comp x_cmpLe

                        ScaOp_Identifier QCOL: [Ord].OrderDate

                        ScaOp_Const TI(date,Null,ML=3) XVAR(date,Not Owned,Value=(735598))

            LogOp_Get TBL: Purchasing.PurchaseOrderLines(alias TBL: OrdDet) Purchasing.PurchaseOrderLines TableID=1554104577 TableReferenceID=0 IsRow: COL: IsBaseRow1001 

            ScaOp_Comp x_cmpEq

                ScaOp_Identifier QCOL: [OrdDet].PurchaseOrderID

                ScaOp_Identifier QCOL: [Ord].PurchaseOrderID

****************************************
*** Stop search, level 1 ***

Fivi Panopoulou

Fivi Panopoulou

Το 2007 ξεκίνησα τις σπουδές μου στη σχολή Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών στο Εθνικό Μετσόβιο Πολυτεχνείο.Κατά την διάρκεια των σπουδών μου εκεί αγάπησα τον προγραμματισμό και τα συστήματα πληροφορικής, καθώς επίσης απέκτησα το ιδιαίτερο ενδιαφέρον μου για τις βάσεις δεδομένων. Κατά την διάρκεια της διπλωματικής μου ασχολήθηκα με ζητήματα ανωνυμοποίησης δεδομένων και την ανάπτυξη σχετικού εργαλείου. Τα τελευταία χρόνια των σπουδών μου, μου δόθηκε η ευκαιρία να ασχοληθώ περισσότερο και να διευρύνω τους ορίζοντές μου ως Microsoft Student Partner και μέσω της κοινότητας Student Guru. Στα πλαίσια των κοινοτήτων αυτών, ξεκίνησα να ασχολούμαι με παρουσιάσεις αλλά και να γνωρίζω τον SQL Server. Από την πρώτη στιγμή που ασχολήθηκα μαζί του, συνειδητοποίησα πόσο ήθελα να εμβαθύνω τις γνώσεις μου σχετικά με αυτόν και τα συστήματα διαχείρισης βάσεων δεδομένων γενικότερα, πράγμα που προσπαθώ να κάνω έκτοτε. Πριν χρόνια είχα την τύχη να συμμετέχω στο πρόγραμμα mentoring, μέσω του οποίου γνώρισα τον κ. Χατζηπαυλή. Από τότε συμμετέχω στην ομάδα του SQLschool.gr.


Sotiris Karras

Sotiris Karras

Είμαι απόφοιτος της σχολής Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών του Εθνικού Μετσόβιου Πολυτεχνείου και στα ενδιαφέροντά μου συμπεριλαμβάνεται o τομέας του Knowledge and Data Engineering. Πιο συγκεκριμένα, έχω ασχοληθεί ακαδημαϊκά και ερευνητικά με τον τομέα του data privacy και data anonymity, ενώ πάθος μου είναι ό,τι έχει να κάνει με relational databases και data management. Στο παρελθόν, έχω συνεργαστεί με την Microsoft Hellas ως Microsoft Student Partner για ακαδημαϊκές δραστηριότητες και ήμουν μέρος του MVP mentoring προγράμματός της, στο οποίο είχα την τύχη να γνωρίσω τον κ. Χατζηπαυλή.

Tip

What's New in SQL Server 2022 - Episodes

More Tips...

Become a member

If you want to receive updates from us become a member to our community.

Connect

Explore

Learn


sqlschool.gr © 2010-2024 All rights reserved

This site uses cookies for operational and analytics purposes only. By continuing to browse this site, you agree to their use.