go backsqlschool blogs list

Outputting SQL Server’s algebrizer bound logical tree

by Fivi Panopoulou - Sotiris Karras

Μέρος του 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 ***

Ημερομηνία: 01 December 2016 21:19
Αξιολόγηση:
Tags:
Share it:

Αφήστε το σχόλιο σας - Leave your comment

Τα σχόλια έχουν κλείσει.
Επιτρέπονται μόνο τα σχόλια από τα μέλη του SqlSchool.gr.


newsletter subscription

Εάν επιθυμείτε να λαμβάνετε ενημέρωση από εμάς, δώστε μας το e-mail σας.
PASS chapter logo
Official Professional Association for SQL Server (PASS) chapter for Greece
Join to PASS