Inside the SQL Server Query Optimizer - part 6 What is the memo?
Hi Guys,
Where did we get to last time?
Last time we had talked about the cost based optimization process and the transformation rules that applied by the optimizer were looking for a better performance plan.
They are stored in a component called memo.
You can find more info about this structure in the “Cascades general optimization framework” developed by Goetz Graefe.
Today I would show you only how the memo work, nothing more!
We should enable some trace flag in order to display the information we need.
To better explain the process we take as example our Query used in the previous posts.
As seen in the previous post our query have this logical tree:
Through the flag 8608 we can take a look to the initial Memo Structure.
You can note, at this point, that the logical tree is simply copied into the memo.
One group per logical node.
Now at the end of the optimization procedure (so after the Search 0, Search 1 and Search 2 phases of witch we speak in detail in the next and last post of this series) we will have in the memo all the optimization applied.
Here our final Memo Structure after the Search optimization phases:
Remember: Each phases can add a new group or an existing group may be expanded to include other logical and physical alternative.
That's all for today.
I hope you enjoyed this post! if so wait for the last post of this series!
Have an amazing week!
See you soon!
Where did we get to last time?
Last time we had talked about the cost based optimization process and the transformation rules that applied by the optimizer were looking for a better performance plan.
The memo
So the question is: Where our alternative plans are stored?They are stored in a component called memo.
You can find more info about this structure in the “Cascades general optimization framework” developed by Goetz Graefe.
Today I would show you only how the memo work, nothing more!
We should enable some trace flag in order to display the information we need.
- Through the trace flag 8608 we can show the initial Memo Structure,
- Through the trace flag 8615 we can show the final Memo Structure,
To better explain the process we take as example our Query used in the previous posts.
SELECT
ANNDOC, NUMDOC, SUM(R.QTA1) AS SUM_QTA
FROM ORDTES T
JOIN ORDRIG R ON R.IDORDTES = T.ID
WHERE
ANNDOC = 2018
GROUP BY ANNDOC, NUMDOC
ORDER BY ANNDOC, NUMDOC
OPTION ( RECOMPILE,
querytraceon 2363,
querytraceon 3604,
querytraceon 8606, -- race flag 8606 will display additional logical trees used during the optimization process
querytraceon 8612, -- Add Extra Info to the Trees Output
querytraceon 8619, -- Show Applied Transformation Rules
querytraceon 8620, -- 8620 = Add memo arguments to trace flag 8619
querytraceon 8608, -- Shows the initial Memo structure
querytraceon 8615, -- Display the final memo structure
querytraceon 8621) -- 8621 = Rule with resulting tree
Through the flag 8608 we can take a look to the initial Memo Structure.
You can note, at this point, that the logical tree is simply copied into the memo.
One group per logical node.
****************************************
--- Initial Memo Structure ---
Root Group 14: Card=1635.67 (Max=8.4478e+010, Min=0)
0 LogOp_GbAgg 9 13 (Distance = 0)
Group 13:
0 AncOp_PrjList 12 (Distance = 0)
Group 12:
0 AncOp_PrjEl 11 (Distance = 0)
Group 11:
0 ScaOp_AggFunc 10 (Distance = 0)
Group 10:
0 ScaOp_Identifier (Distance = 0)
Group 9: Card=66408.4 (Max=8.4478e+010, Min=0)
0 LogOp_Join 4 5 8 (Distance = 0)
Group 8:
0 ScaOp_Comp 6 7 (Distance = 0)
Group 7:
0 ScaOp_Identifier (Distance = 0)
Group 6:
0 ScaOp_Identifier (Distance = 0)
Group 5: Card=566688 (Max=623357, Min=0)
0 LogOp_Get (Distance = 0)
Group 4: Card=1641 (Max=135521, Min=0)
0 LogOp_Select 0 3 (Distance = 0)
Group 3:
0 ScaOp_Comp 1 2 (Distance = 0)
Group 2:
0 ScaOp_Const (Distance = 0)
Group 1:
0 ScaOp_Identifier (Distance = 0)
Group 0: Card=123201 (Max=135521, Min=0)
0 LogOp_Get (Distance = 0)
Now at the end of the optimization procedure (so after the Search 0, Search 1 and Search 2 phases of witch we speak in detail in the next and last post of this series) we will have in the memo all the optimization applied.
Here our final Memo Structure after the Search optimization phases:
Remember: Each phases can add a new group or an existing group may be expanded to include other logical and physical alternative.
--- Final Memo Structure ---
Group 32: Card=566688 (Max=623357, Min=0)
0 LogOp_Spool 5 (Distance = 1)
Group 31: Card=46607.6 (Max=623357, Min=0)
0 LogOp_Spool 22 (Distance = 3)
Group 30: Card=1 (Max=135521, Min=0)
0 LogOp_SelectRes 29 3 (Distance = 4)
Group 29: Card=1 (Max=135521, Min=0)
0 LogOp_SelectIdx 28 8 (Distance = 4)
Group 28: Card=123201 (Max=135521, Min=0)
0 LogOp_GetIdx (Distance = 4)
Group 27: Card=1 (Max=135521, Min=0)
1 PhyOp_Range 5 ASC 26.0 Cost(RowGoal 0,ReW 0.0512361,ReB 46606.6,Dist 46607.6,Total 46607.6)= 7.37882 (Distance = 5)
0 LogOp_SelectIdx 25 26 (Distance = 4)
Group 26:
0 ScaOp_Logical 8.0 3.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 7 (Distance = 4)
Group 25: Card=123201 (Max=135521, Min=0)
0 LogOp_GetIdx (Distance = 4)
Group 24: Card=566688 (Max=623357, Min=0)
1 PhyOp_Range 1 ASC Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 26.8615 (Distance = 2)
0 LogOp_GetIdx (Distance = 1)
Group 23: Card=1641 (Max=135521, Min=0)
3 PhyOp_HashJoinx_jtInner 4.1 22.1 8.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 32.1464 (Distance = 3)
2 PhyOp_Sort 23.3 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 32.1851 (Distance = 0)
1 LogOp_Join 22 4 8 (Distance = 3)
0 LogOp_Join 4 22 8 (Distance = 2)
Group 22: Card=46607.6 (Max=623357, Min=0)
6 PhyOp_Sort 22.1 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 35.1172 (Distance = 0)
1 PhyOp_HashGbAgg 5.2 16.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 31.7882 (Distance = 3)
0 LogOp_GbAgg 5 16 (Distance = 2)
Group 21:
0 AncOp_PrjList 20.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0 (Distance = 1)
Group 20:
0 AncOp_PrjEl 19.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0 (Distance = 1)
Group 19:
0 ScaOp_AggFunc 18.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 2 (Distance = 1)
Group 18:
0 ScaOp_Identifier Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 1 (Distance = 1)
Group 17: Card=6542.61 (Max=8.4478e+010, Min=0)
2 PhyOp_HashGbAgg 9.2 16.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 31.1182 (Distance = 2)
1 PhyOp_Sort 17.2 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 31.3337 (Distance = 0)
0 LogOp_GbAgg 9 16 (Distance = 1)
Group 16:
0 AncOp_PrjList 15.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0 (Distance = 1)
Group 15:
0 AncOp_PrjEl 11.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0 (Distance = 1)
Root Group 14: Card=1635.67 (Max=8.4478e+010, Min=0)
11 PhyOp_HashGbAgg 9.2 13.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 31.0412 (Distance = 1)
9 PhyOp_Sort 14.11 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 31.0798 (Distance = 0)
2 LogOp_GbAgg 23 21 (Distance = 2)
1 LogOp_GbAgg 17 21 (Distance = 1)
0 LogOp_GbAgg 9 13 (Distance = 0)
Group 13:
0 AncOp_PrjList 12.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0 (Distance = 0)
Group 12:
0 AncOp_PrjEl 11.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0 (Distance = 0)
Group 11:
0 ScaOp_AggFunc 10.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 2 (Distance = 0)
Group 10:
0 ScaOp_Identifier Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 1 (Distance = 0)
Group 9: Card=66408.4 (Max=8.4478e+010, Min=0)
8 PhyOp_Sort 9.2 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 35.5838 (Distance = 0)
2 PhyOp_HashJoinx_jtInner 4.1 5.2 8.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 30.6896 (Distance = 1)
1 LogOp_Join 5 4 8 (Distance = 1)
0 LogOp_Join 4 5 8 (Distance = 0)
Group 8:
0 ScaOp_Comp 6.0 7.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 3 (Distance = 0)
Group 7:
0 ScaOp_Identifier Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 1 (Distance = 0)
Group 6:
0 ScaOp_Identifier Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 1 (Distance = 0)
Group 5: Card=566688 (Max=623357, Min=0)
6 PhyOp_Sort 5.2 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 76.5855 (Distance = 0)
2 PhyOp_Range 1 ASC Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 26.8615 (Distance = 1)
0 LogOp_Get (Distance = 0)
Group 4: Card=1641 (Max=135521, Min=0)
1 PhyOp_Range 5 ASC 3.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0.00675377 (Distance = 1)
0 LogOp_Select 0 3 (Distance = 0)
Group 3:
0 ScaOp_Comp 1.0 2.0 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 3 (Distance = 0)
Group 2:
0 ScaOp_Const Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 1 (Distance = 0)
Group 1:
0 ScaOp_Identifier Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 1 (Distance = 0)
Group 0: Card=123201 (Max=135521, Min=0)
0 LogOp_Get (Distance = 0)
That's all for today.
I hope you enjoyed this post! if so wait for the last post of this series!
Have an amazing week!
See you soon!
Luca Biondi @ SQLServerPerformance blog!
Comments
Post a Comment