3. 3
Explore Everything PASS Has to Offer
FREE SQL SERVER AND BI WEB EVENTS FREE 1-DAY TRAINING EVENTS REGIONAL EVENT
LOCAL USER GROUPS AROUND
THE WORLD
FREE ONLINE TECHNICAL TRAINING
THIS IS COMMUNITY BUSINESS ANALYTICS TRAINING
SESSION RECORDINGS PASS NEWSLETTER
4. Agenda
We will be taking a look at Graphical Execution Plans from a beginners
perspective. The ride will include the following:
• Execution Steps
• Execution Plan Basics
• Basic Operators
• Join Operators
• Other Operators
4
6. 6
On The Inside
Relational Engine
Optimizer
Command
Parser
Query
Executor
SNI*
User
Storage Engine
Buffer
Manager
Access
Methods
Transaction
Manager
SQL OS
Buffer Pool
Borrowed from Bradley Ball’s “SQL Internals, Recovery Models, & Backups” presentation
Plan Cache
Data
Cache
Data
*SQL Server Network Interface (SNI)
7. Relation Engine
1. Is the query syntactically correct?
SELECT [Name], [Number] FORM [Production].[Product]
Incorrect syntax near 'Production'.
SELCT [Name], [Number] FROM [Production].[Product]
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'FROM'.
2. No Errors will be Output as Parse Tree to Algebrizer
Query Parsing
7
10. 10
Create Plan
Execute
Parallel/
Not Parallel
Store in Plan
Cache (*)
Aggregate
Binding
Resolve
Data Types
Name
Resolution
Plan Creation
Algebrizer Query Optimizer
Recompile?
Storage Engine
No Results
Returned
7
Cost >
Cost for
Parallelism
8
No
Find Plan
Does Plan
Exist?
5
Yes
Hash Checked
in Plan Cache
3 4
6
1 2
5
11. What is a Hash?
A hash is a number that is generated by reading the contents of a document or
message. Different messages should generate different hash values, but the
same message causes the algorithm to generate the same hash value.
SELECT HASHBYTES('SHA','Hellow World')
0x5F341D31F6B6A8B15BC4E6704830BF37F99511D1
SELECT HASHBYTES('SHA','Hello World')
0x0A4D55A8D778E5022FAB701977C5D840BBC486D0
SELECT HASHBYTES('SHA','Hello World')
0xC2F14A3E371A79A792E6ED78FB07A4B0C26618B4
https://technet.microsoft.com/en-us/library/cc837966(v=sql.100).aspx
12. 13
Cardinality Estimation
The optimization process depends on a cost estimation of each physical operator and the
estimated number of records (cardinality estimation) to be processed.
DBCC SHOW_STATISTICS ("[Sales].[SalesOrderDetailEnlarged]",
[PK_SalesOrderDetailEnlarged_SalesOrderID_SalesOrderDetailID]) WITH HISTOGRAM;
GO
The accuracy of the cardinality estimation depends upon the distribution of values in one or more
columns of a table (statistics).
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
43659 0 12 0 1
47355 16015 68 3695 4.334236
51739 24056 72 4383 5.488478
57046 20733 67 5306 3.907463
65174 27775 48 8127 3.41762
101719 131906 36 36544 3.609512
107533 22424 60 5813 3.857561
13. 14
Cardinality Estimation
There are multiple factors that can negatively impact the cardinality estimation
process:
1. Out of date Statistics
SELECT object_name(object_id) as TableName, name AS stats_name,
STATS_DATE(object_id, stats_id) AS statistics_update_date
FROM sys.stats
WHERE object_id = OBJECT_ID('[Sales].[SalesOrderDetailEnlarged]');
2. Cardinality Estimation Errors
https://www.sqlskills.com/blogs/joe/cardinality-estimation-model-version/
16. 17
Required Permissions
Server or database roles with permissions:
sysadmin, dbcreator or db_owner or showplan
To give showplan rights to the database:
GRANT SHOWPLAN TO [username];
21. 22
Nested Loop
Non-blocking
Description
For each row in the top (outer) input, scan the
bottom (inner) input, and output matching rows.
Where does it happen: Joins with
indexes on join columns.
22. Nested Loop
SELECT [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[OrderDate]
FROM [Sales].[SalesOrderHeader] soh
JOIN [Sales].[SalesOrderDetail] sod
ON sod.[SalesOrderID] = soh.[SalesOrderID]
WHERE soh.[OrderDate] = '2013-08-30 00:00:00.000'
Non-blocking
23
23. Nested Loop
SELECT [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[OrderDate]
FROM [Sales].[SalesOrderHeader] soh
JOIN [Sales].[SalesOrderDetail] sod
ON sod.[SalesOrderID] = soh.[SalesOrderID]
WHERE soh.[OrderDate] = '2013-08-30 00:00:00.000'
Outer Loop
Inner Loop
Non-blocking
24
26. 27
Description
Match rows from two suitably sorted input
tables exploiting their sort order.
Where does it happen: Joins with
indexes on join columns sorted in an
appropriate sort order.
Merge
Non-blocking
29. 30
Hash Match
Description
Use each row from the top input to build a hash
table, and each row from the bottom input to
probe into the hash table, outputting all
matching rows.
Where does it happen: Missing Index,
Missing Where Clause, Where Clause that is
non-sargable.
30. Hash Match
Blocking
SELECT [sod1].[ProductID], [sod1].[CarrierTrackingNumber], [sod1].[UnitPrice], [sod1].[OrderQty]
FROM [Sales].[SalesOrderDetail] sod1
JOIN [Sales].[SalesOrderDetail] sod2
ON [sod1].[ProductID] = [sod2].[ProductID]
AND [sod1].[CarrierTrackingNumber] = [sod2].[CarrierTrackingNumber]
AND [sod1].[OrderQty] > 5
31
32. Hash Match
Hash Table 1
Blocking
33
8Ax94Dd343S
1) From the first input (table) the
column data is hashed and put in
buckets in a “hash” table (in
tempdb).
2) Then it reads rows from input 2,
hashes the join columns and
compares the hash and values to
output matches.
8Ax94Dd343S
8Bx40XdF43D
8CxXDVa91f If a Match…
“Send” row data to next
operator and go to the next row.
35. 36
Parallelism
SELECT [sod1].[ProductID], [sod1].[CarrierTrackingNumber], [sod1].[UnitPrice], [sod1].[OrderQty]
FROM [Sales].[SalesOrderDetail] sod1
JOIN [Sales].[SalesOrderDetail] sod2
ON [sod1].[ProductID] = [sod2].[ProductID]
AND [sod1].[CarrierTrackingNumber] = [sod2].[CarrierTrackingNumber]
36. 37
Parallelism
SET STATISTICS IO ON
SET STATISTICS TIME ON
SELECT [sod1].[ProductID], [sod1].[CarrierTrackingNumber], [sod1].[UnitPrice], [sod1].[OrderQty]
FROM [Sales].[SalesOrderDetail] sod1
JOIN [Sales].[SalesOrderDetail] sod2
ON [sod1].[ProductID] = [sod2].[ProductID]
AND [sod1].[CarrierTrackingNumber] = [sod2].[CarrierTrackingNumber]
SELECT [sod1].[ProductID], [sod1].[CarrierTrackingNumber], [sod1].[UnitPrice], [sod1].[OrderQty]
FROM [Sales].[SalesOrderDetail] sod1
JOIN [Sales].[SalesOrderDetail] sod2
ON [sod1].[ProductID] = [sod2].[ProductID]
AND [sod1].[CarrierTrackingNumber] = [sod2].[CarrierTrackingNumber]
OPTION(MAXDOP 1)
39. 40
Hash Aggregate
SELECT [sod1].[CarrierTrackingNumber], sum([sod1].[UnitPrice]) UnitPriceTotal,
sum([sod1].[OrderQty]) as OrderQtyTotal
FROM [Sales].[SalesOrderDetail] sod1
JOIN [Sales].[SalesOrderDetail] sod2
ON [sod1].[ProductID] = [sod2].[ProductID]
AND [sod1].[CarrierTrackingNumber] = [sod2].[CarrierTrackingNumber]
AND [sod1].[OrderQty] > 5
GROUP BY [sod1].[CarrierTrackingNumber]
40. 41
Stream Aggregate
SELECT [sod1].[CarrierTrackingNumber], sum([sod1].[UnitPrice])
UnitPriceTotal, sum([sod1].[OrderQty]) as OrderQtyTotal
FROM [Sales].[SalesOrderDetail] sod1
JOIN [Sales].[SalesOrderDetail] sod2
ON [sod1].[ProductID] = [sod2].[ProductID]
AND [sod1].[CarrierTrackingNumber] = [sod2].[CarrierTrackingNumber]
AND [sod1].[OrderQty] > 5
GROUP BY [sod1].[CarrierTrackingNumber]
41. 42
Sort Spill
Operator used tempdb to spill data during execution with spill level 2
SELECT [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[OrderDate]
FROM [Sales].[SalesOrderHeader] soh
JOIN [Sales].[SalesOrderDetailEnlarged] sod
ON sod.[SalesOrderID] = soh.[SalesOrderID]
WHERE [sod].[CarrierTrackingNumber] > '41D0-42A8-A5'
ORDER BY [soh].[RevisionNumber], [soh].[OrderDate]
42. 43
Sort Spill
SELECT TOP 1 [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[OrderDate]
FROM [Sales].[SalesOrderHeader] soh
JOIN [Sales].[SalesOrderDetailEnlarged] sod
ON sod.[SalesOrderID] = soh.[SalesOrderID]
WHERE [sod].[CarrierTrackingNumber] > '41D0-42A8-A5'
ORDER BY [soh].[RevisionNumber], [soh].[OrderDate]
43. 44
Implicit Conversion
SELECT [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[OrderDate]
FROM [Sales].[SalesOrderHeaderEnlarged] soh
JOIN [Sales].[SalesOrderDetailEnlarged] sod
ON sod.[SalesOrderID] = soh.[SalesOrderID]
WHERE CONVERT(varchar(10),[soh].[OrderDate],110) = '04-14-2014'
44. Parameter Sniffing
During the optimization phase the parameters supplied to the parameterized
query or stored procedure are used to determine how well an index will work
based upon the statistics.
It usually results in a better plan, but sometimes do to skewed distribution of
data is results in bad parameter sniffing.
45. 46
SQL Server 2016 Live Query
Live Query works with SQL Server 2014 + using SSMS 2016
SELECT pr.Name as ProductName, sod.OrderQty, sod.UnitPrice, soh.OrderDate
FROM [Sales].[SalesOrderDetailEnlarged] sod
JOIN [Sales].[SalesOrderHeaderEnlarged] soh
ON soh.SalesOrderID = sod.SalesOrderID
JOIN [Production].[Product] pr
ON pr.ProductID = sod.ProductID
WHERE soh.OrderDate between '2014-10-01' AND '2015-10-01'
OPTION(MAXDOP 1)
49. 51
Session Evaluations
ways to access
Go to
passsummit.com/evals
Download the GuideBook App
and search: PASS Summit 2015
Follow the QR code link displayed
on session signage throughout the
conference venue and in the
program guide
Submit by 5pm
Friday November 6th to
WIN prizes
Your feedback is
important and valuable.
The query optimizer checks the hash against the plan cache. If it exists use it and the optimization step is skipped and plan is passed to query execution.
The query optimizer uses the query processor tree and the statistics to determine an estimated execution plan.
The optimizer goes through a process of using different types of joins and indexes and assigns a cost to each step by CPU and I/O and determines a cost for each possible estimated plan it generates.
Once an acceptable estimated plan is found it is stored in the plan cache then sent to the query execution.
The query optimizer checks the hash against the plan cache. If it exists use it and the optimization step is skipped and plan is passed to query execution.
The query optimizer uses the query processor tree and the statistics to determine an estimated execution plan.
The optimizer goes through a process of using different types of joins and indexes and assigns a cost to each step by CPU and I/O and determines a cost for each possible estimated plan it generates.
Once an acceptable estimated plan is found it is stored in the plan cache then sent to the query execution.
Zoomit to show fine print!
Cardinality Estimation Model Version 120 (new model) 70 old model.
Cardinality Estimation Model Version 120 (new model) 70 old model.
Physical order of process is SELECT pulls data from the next operator left to right top to bottom.
Easier to understand from right to left top to bottom.
Seeing a hash match is a good indication of an opportunity for tuning by adding an index, improving the join or where clause. If that isn’t possible, the hash match is the most efficient option you have.
In the first input, the data is hashed then dropped into a hash bucket. Then a hash is applied to the data in the second input. There can be duplicates in the bucket so an additional predicate comparison to ensure join uniqueness.
In the first input, the data is hashed then dropped into a hash bucket. Then a hash is applied to the data in the second input. There can be duplicates in the bucket so an additional predicate comparison to ensure join uniqueness.