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