SlideShare a Scribd company logo
Execution Plans for Mere Mortals
A beginners overview of execution
plans and what to look for.
Who Am I?
Mike Lawell
Mike Lawell
Principal Consultant
Twitter: @SQLDiver
Blog: SQLServerAssociates.com
LinkedIn: LinkedIn.com/in/MikeLawell
EXECUTION STEPS
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
Query Parsing
Relation Engine
1. Is the query syntactically correct?
SELECT [Nmae], [Number] FROM [Production].[Product]
Msg 207, Level 16, State 1, Line 3
Invalid column name 'Nmae'.
SELCT [Name], [Number] FROM [Production].[Product]
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'FROM'.
2. No Errors Output as Parse Tree to Algebrizer
Query Parsing
SELECT [Nmae], [Number] FROM [Production].[Product]
Msg 207, Level 16, State 1, Line 3
Invalid column name 'Nmae'.
Query Parsing
SELECT [Name], [Number] FROM [Production].[Product]
Algebrizer
1. Resolve the Names of the objects (tables, columns, etc.)
2. Resolve the data types for the objects being accessed.
3. Finds aggregate operations (min, max, group by) and performs an operation
called aggregate binding.
If the names of the objects, columns aren’t found an error is output and the process
halts.
If it is successful the algebrizer outputs the query processor tree to the query
optimizer. The query hash is generated and passed with the query processor tree.
Query Optimizer
1. 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.
2. The query optimizer uses the query processor tree and the statistics to determine
an estimated execution plan.
3. 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.
4. Once an acceptable estimated plan is found it is stored in the plan cache then sent
to the query execution.
Query Execution
Storage Engine
1. The storage engine determines if a recompile was triggered causing a change in
the estimated execution plan.
2. SQL Server determines based upon cost whether it exceeds the threshold for
parallelism changing the estimated plan for parallelism.
3. Statistics that have changed causing a change in the estimated plan.
SQL Server returns the results.
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]", [_WA_Sys_00000003_3D7E1B63]);
The accuracy of the cardinality estimation depends upon the distribution of values in one or
more columns of a table (statistics).
Name Updated Rows Rows Sampled Steps Average key length String Index Filter Expression Unfiltered Rows
_WA_Sys_00000003_3D7E1B63 Nov 26 2014 11:26AM 1000 1000 196 24 YES NULL 1000
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
002EE045-E30 0 1 0 1
0169388E-8EC 6 1 6 1
031622B3-B68 3 1 3 1
0424F840-4C2 3 1 3 1
04C4FEAC-7C1 3 1 3 1
Swag Question
Name
_WA_Sys_00000003_3D7E1B63
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/
Swag Question
Why 70 vs 120?
EXECUTION PLAN BASICS
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];
How to Read
BASIC OPERATORS
Basic Operators
JOIN OPERATORS
Nested LoopNon-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.
Nested Loop
SELECT [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[Ord
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
Outer
Inner
Nested Loop
SalesOrderID RevisionNumber OrderDate
55233 8 2013-08-30 00:00:00.000
55234 8 2013-08-30 00:00:00.000
55235 8 2013-08-30 00:00:00.000
55236 8 2013-08-30 00:00:00.000
55237 8 2013-08-30 00:00:00.000
55238 8 2013-08-30 00:00:00.000
55239 8 2013-08-30 00:00:00.000
55240 8 2013-08-30 00:00:00.000
55241 8 2013-08-30 00:00:00.000
55242 8 2013-08-30 00:00:00.000
55243 8 2013-08-30 00:00:00.000
55244 8 2013-08-30 00:00:00.000
55245 8 2013-08-30 00:00:00.000
55246 8 2013-08-30 00:00:00.000
55247 8 2013-08-30 00:00:00.000
55248 8 2013-08-30 00:00:00.000
55249 8 2013-08-30 00:00:00.000
55250 8 2013-08-30 00:00:00.000
55251 8 2013-08-30 00:00:00.000
55252 8 2013-08-30 00:00:00.000
55253 8 2013-08-30 00:00:00.000
SalesOrderID ProductID CarrierTrackingNumber OrderQt
55233 738 1590-499E-95 5
55233 792 1590-499E-95 5
55233 793 1590-499E-95 4
55233 794 1590-499E-95 4
55233 795 1590-499E-95 4
55233 796 1590-499E-95 5
55233 797 1590-499E-95 6
55233 798 1590-499E-95 2
55233 799 1590-499E-95 1
55233 800 1590-499E-95 1
55233 801 1590-499E-95 6
55233 835 1590-499E-95 6
55233 874 1590-499E-95 8
55233 875 1590-499E-95 8
55233 938 1590-499E-95 5
55233 939 1590-499E-95 5
55233 940 1590-499E-95 4
55233 973 1590-499E-95 5
55233 974 1590-499E-95 1
55233 975 1590-499E-95 1
Non-blocking
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.
MergeNon-blocking
MergeNon-blocking
SELECT [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[OrderDate]
FROM [Sales].[SalesOrderHeader] soh
JOIN [Sales].[SalesOrderDetail] sod
ON sod.[SalesOrderID] = soh.[SalesOrderID]
MergeNon-blocking
SalesOrderID RevisionNumber OrderDate
55233 8 2013-08-30 00:00:00.000
55234 8 2013-08-30 00:00:00.000
55235 8 2013-08-30 00:00:00.000
55236 8 2013-08-30 00:00:00.000
55237 8 2013-08-30 00:00:00.000
55238 8 2013-08-30 00:00:00.000
55239 8 2013-08-30 00:00:00.000
55240 8 2013-08-30 00:00:00.000
55241 8 2013-08-30 00:00:00.000
55242 8 2013-08-30 00:00:00.000
55243 8 2013-08-30 00:00:00.000
55244 8 2013-08-30 00:00:00.000
55245 8 2013-08-30 00:00:00.000
55246 8 2013-08-30 00:00:00.000
55247 8 2013-08-30 00:00:00.000
55248 8 2013-08-30 00:00:00.000
55249 8 2013-08-30 00:00:00.000
55250 8 2013-08-30 00:00:00.000
55251 8 2013-08-30 00:00:00.000
55252 8 2013-08-30 00:00:00.000
55253 8 2013-08-30 00:00:00.000
SalesOrderID ProductID CarrierTrackingNumber OrderQt
55233 738 1590-499E-95 5
55233 792 1590-499E-95 5
55233 793 1590-499E-95 4
55233 794 1590-499E-95 4
55233 795 1590-499E-95 4
55233 796 1590-499E-95 5
55233 797 1590-499E-95 6
55233 798 1590-499E-95 2
55233 799 1590-499E-95 1
55233 800 1590-499E-95 1
55233 801 1590-499E-95 6
55233 835 1590-499E-95 6
55233 874 1590-499E-95 8
55233 875 1590-499E-95 8
55233 938 1590-499E-95 5
55233 939 1590-499E-95 5
55233 940 1590-499E-95 4
55233 973 1590-499E-95 5
55233 974 1590-499E-95 1
55233 975 1590-499E-95 1
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.
Hash MatchBlocking
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
Hash MatchBlocking
ProductID CarrierTrackingNumber Hash
707 4BC2-4C6D-83 -767544381
711 2AA4-4D12-9F -767515863
715 C811-4D40-80 -767499885
715 8FCD-4D55-8F -767496256
714 CC2F-4D47-8C -767488607
712 BE3B-4D30-A7 -767488106
707 9EBF-4C7E-82 -767471833
716 F78B-4D68-8E -767470049
712 8EBE-4D2C-AB -767459569
716 7DE5-4D74-A7 -767455808
715 46EF-4D44-A9 -767449380
711 9FC2-4D08-A7 -767447057
ProductID CarrierTrackingNumbe
736 2554-4F68-AB -767556491
717 9526-4D73-83 -767556433
715 CC2F-4D47-8C -767554143
715 2960-4D59-96 -767553412
722 9708-4E22-A4 -767551834
722 6F5C-4E3C-B5 -767549829
717 7E0A-4D6E-9E -767545458
707 4BC2-4C6D-83 -767544381
716 F108-4D76-8A -767543168
711 B900-4D0D-AF -767541067
711 67A0-4D10-87 -767539667
707 8441-4C6F-89 -767535798
Hash Table 1 Hash Table 2
Fixed Hash Match
OTHER OPERATORS
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]
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)
Parallelism
Table 'SalesOrderDetail'. Scan count 18, logical reads 2490, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob
read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads
0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead
reads 0.
SQL Server Execution Times:
CPU time = 9593 ms, elapsed time = 2381 ms.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads
0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead
reads 0.
Table 'SalesOrderDetail'. Scan count 2, logical reads 2490, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-
ahead reads 0.
SQL Server Execution Times:
CPU time = 7941 ms, elapsed time = 8372 ms.
Parallelism
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]
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]
Sort (spill)
Operator used tempdb to spill data during execution with spill level 1
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]
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]
Implicit Conversion
SELECT [sod].[ProductID], [sod].[CarrierTrackingNumber], [sod].[UnitPrice], [sod].[OrderQty], [rowguid]
FROM [Sales].[SalesOrderDetail] sod
WHERE LEFT([sod].[rowguid],4) = N'FE10'
Properties
Cool Tools/Products
SQL Server Query Plan Analysis by Joe Sack
Resources
http://www.red-gate.com/community/books/
Downloadable
FREE!
Thank You!
Mike Lawell
Principal Consultant
Twitter: @SQLDiver
Blog: SQLServerAssociates.com
LinkedIn: LinkedIn.com/in/MikeLawell
Email: mike@sqlserverassociates.com
Who Am I?
Mike Lawell
Mike Lawell
Principal Consultant
Twitter: @SQLDiver
Blog: SQLServerAssociates.com
LinkedIn: LinkedIn.com/in/MikeLawell

More Related Content

PPTX
Mike lawell executionplansformeremortals_2015
DOCX
DBMS LAB
PDF
2018 vegas-mstr world- cisco jacob-mathew_preso-final-longversion-fordist - copy
PDF
Ecuacionesfuncionales2 1
PDF
Ecuacionesfuncionales1 1
PDF
1242361147my upload ${file.name}
PDF
arrow electronics annual reports2002
PPTX
Keynote Speech AsiaCALL conference 2011
Mike lawell executionplansformeremortals_2015
DBMS LAB
2018 vegas-mstr world- cisco jacob-mathew_preso-final-longversion-fordist - copy
Ecuacionesfuncionales2 1
Ecuacionesfuncionales1 1
1242361147my upload ${file.name}
arrow electronics annual reports2002
Keynote Speech AsiaCALL conference 2011

Viewers also liked (10)

PPTX
Deepam annual report 2013-14
PPTX
Film Trailer Analysis
PDF
Legge stabilità 2015
PPTX
Mise en-scene/hospital scene
PPTX
Advertising Site Is Helping Us Have Our Dream Child
PPTX
Marketing via E-mail for Search Engines
PPTX
Distributed marketing marketing automation summit - artoos
PPTX
Mood board
PPTX
Discount drug card association ny
PPTX
Audience Theory
Deepam annual report 2013-14
Film Trailer Analysis
Legge stabilità 2015
Mise en-scene/hospital scene
Advertising Site Is Helping Us Have Our Dream Child
Marketing via E-mail for Search Engines
Distributed marketing marketing automation summit - artoos
Mood board
Discount drug card association ny
Audience Theory
Ad

Similar to Execution plans for mere mortals (20)

PDF
Explaining the explain_plan
PPTX
SQL Server 2012 Best Practices
PPTX
Ground Breakers Romania: Explain the explain_plan
PPTX
DOAG: Visual SQL Tuning
PDF
kscope2013vst-130627142814-phpapp02.pdf
PPTX
Introduction to execution plan analysis
PPTX
SQL Tuning Methodology, Kscope 2013
PDF
Find it. Fix it. Real-World SQL Tuning Cases with Karen Morton
PDF
Managing Statistics for Optimal Query Performance
PDF
Brad McGehee Intepreting Execution Plans Mar09
PDF
Brad McGehee Intepreting Execution Plans Mar09
PPTX
Building scalable application with sql server
PDF
Oracle12 for Developers - Oracle OpenWorld Preview AMIS
PDF
Oracle12c For Developers
PPTX
Part3 Explain the Explain Plan
PPTX
SQL Tuning and VST
PDF
SQL Performance Solutions: Refactor Mercilessly, Index Wisely
PDF
Presentation interpreting execution plans for sql statements
PPTX
Part1 of SQL Tuning Workshop - Understanding the Optimizer
PPTX
Oracle sql high performance tuning
Explaining the explain_plan
SQL Server 2012 Best Practices
Ground Breakers Romania: Explain the explain_plan
DOAG: Visual SQL Tuning
kscope2013vst-130627142814-phpapp02.pdf
Introduction to execution plan analysis
SQL Tuning Methodology, Kscope 2013
Find it. Fix it. Real-World SQL Tuning Cases with Karen Morton
Managing Statistics for Optimal Query Performance
Brad McGehee Intepreting Execution Plans Mar09
Brad McGehee Intepreting Execution Plans Mar09
Building scalable application with sql server
Oracle12 for Developers - Oracle OpenWorld Preview AMIS
Oracle12c For Developers
Part3 Explain the Explain Plan
SQL Tuning and VST
SQL Performance Solutions: Refactor Mercilessly, Index Wisely
Presentation interpreting execution plans for sql statements
Part1 of SQL Tuning Workshop - Understanding the Optimizer
Oracle sql high performance tuning
Ad

Recently uploaded (20)

PDF
Optimise Shopper Experiences with a Strong Data Estate.pdf
PPTX
(Ali Hamza) Roll No: (F24-BSCS-1103).pptx
PPTX
FMIS 108 and AISlaudon_mis17_ppt_ch11.pptx
PPTX
retention in jsjsksksksnbsndjddjdnFPD.pptx
PDF
Votre score augmente si vous choisissez une catégorie et que vous rédigez une...
PPTX
CYBER SECURITY the Next Warefare Tactics
PDF
annual-report-2024-2025 original latest.
PDF
Introduction to Data Science and Data Analysis
PPTX
IMPACT OF LANDSLIDE.....................
PPTX
Business_Capability_Map_Collection__pptx
PPTX
STERILIZATION AND DISINFECTION-1.ppthhhbx
PPTX
Introduction to Inferential Statistics.pptx
PPT
DU, AIS, Big Data and Data Analytics.ppt
PDF
Data Engineering Interview Questions & Answers Batch Processing (Spark, Hadoo...
PPT
lectureusjsjdhdsjjshdshshddhdhddhhd1.ppt
PPTX
Leprosy and NLEP programme community medicine
PDF
REAL ILLUMINATI AGENT IN KAMPALA UGANDA CALL ON+256765750853/0705037305
PPTX
Microsoft-Fabric-Unifying-Analytics-for-the-Modern-Enterprise Solution.pptx
PDF
[EN] Industrial Machine Downtime Prediction
PPTX
New ISO 27001_2022 standard and the changes
Optimise Shopper Experiences with a Strong Data Estate.pdf
(Ali Hamza) Roll No: (F24-BSCS-1103).pptx
FMIS 108 and AISlaudon_mis17_ppt_ch11.pptx
retention in jsjsksksksnbsndjddjdnFPD.pptx
Votre score augmente si vous choisissez une catégorie et que vous rédigez une...
CYBER SECURITY the Next Warefare Tactics
annual-report-2024-2025 original latest.
Introduction to Data Science and Data Analysis
IMPACT OF LANDSLIDE.....................
Business_Capability_Map_Collection__pptx
STERILIZATION AND DISINFECTION-1.ppthhhbx
Introduction to Inferential Statistics.pptx
DU, AIS, Big Data and Data Analytics.ppt
Data Engineering Interview Questions & Answers Batch Processing (Spark, Hadoo...
lectureusjsjdhdsjjshdshshddhdhddhhd1.ppt
Leprosy and NLEP programme community medicine
REAL ILLUMINATI AGENT IN KAMPALA UGANDA CALL ON+256765750853/0705037305
Microsoft-Fabric-Unifying-Analytics-for-the-Modern-Enterprise Solution.pptx
[EN] Industrial Machine Downtime Prediction
New ISO 27001_2022 standard and the changes

Execution plans for mere mortals

  • 1. Execution Plans for Mere Mortals A beginners overview of execution plans and what to look for.
  • 2. Who Am I? Mike Lawell Mike Lawell Principal Consultant Twitter: @SQLDiver Blog: SQLServerAssociates.com LinkedIn: LinkedIn.com/in/MikeLawell
  • 4. 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
  • 5. Query Parsing Relation Engine 1. Is the query syntactically correct? SELECT [Nmae], [Number] FROM [Production].[Product] Msg 207, Level 16, State 1, Line 3 Invalid column name 'Nmae'. SELCT [Name], [Number] FROM [Production].[Product] Msg 156, Level 15, State 1, Line 3 Incorrect syntax near the keyword 'FROM'. 2. No Errors Output as Parse Tree to Algebrizer
  • 6. Query Parsing SELECT [Nmae], [Number] FROM [Production].[Product] Msg 207, Level 16, State 1, Line 3 Invalid column name 'Nmae'.
  • 7. Query Parsing SELECT [Name], [Number] FROM [Production].[Product]
  • 8. Algebrizer 1. Resolve the Names of the objects (tables, columns, etc.) 2. Resolve the data types for the objects being accessed. 3. Finds aggregate operations (min, max, group by) and performs an operation called aggregate binding. If the names of the objects, columns aren’t found an error is output and the process halts. If it is successful the algebrizer outputs the query processor tree to the query optimizer. The query hash is generated and passed with the query processor tree.
  • 9. Query Optimizer 1. 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. 2. The query optimizer uses the query processor tree and the statistics to determine an estimated execution plan. 3. 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. 4. Once an acceptable estimated plan is found it is stored in the plan cache then sent to the query execution.
  • 10. Query Execution Storage Engine 1. The storage engine determines if a recompile was triggered causing a change in the estimated execution plan. 2. SQL Server determines based upon cost whether it exceeds the threshold for parallelism changing the estimated plan for parallelism. 3. Statistics that have changed causing a change in the estimated plan. SQL Server returns the results.
  • 11. 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]", [_WA_Sys_00000003_3D7E1B63]); The accuracy of the cardinality estimation depends upon the distribution of values in one or more columns of a table (statistics). Name Updated Rows Rows Sampled Steps Average key length String Index Filter Expression Unfiltered Rows _WA_Sys_00000003_3D7E1B63 Nov 26 2014 11:26AM 1000 1000 196 24 YES NULL 1000 RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS 002EE045-E30 0 1 0 1 0169388E-8EC 6 1 6 1 031622B3-B68 3 1 3 1 0424F840-4C2 3 1 3 1 04C4FEAC-7C1 3 1 3 1
  • 13. 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. 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. Nested LoopNon-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].[Ord 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 Outer Inner
  • 23. Nested Loop SalesOrderID RevisionNumber OrderDate 55233 8 2013-08-30 00:00:00.000 55234 8 2013-08-30 00:00:00.000 55235 8 2013-08-30 00:00:00.000 55236 8 2013-08-30 00:00:00.000 55237 8 2013-08-30 00:00:00.000 55238 8 2013-08-30 00:00:00.000 55239 8 2013-08-30 00:00:00.000 55240 8 2013-08-30 00:00:00.000 55241 8 2013-08-30 00:00:00.000 55242 8 2013-08-30 00:00:00.000 55243 8 2013-08-30 00:00:00.000 55244 8 2013-08-30 00:00:00.000 55245 8 2013-08-30 00:00:00.000 55246 8 2013-08-30 00:00:00.000 55247 8 2013-08-30 00:00:00.000 55248 8 2013-08-30 00:00:00.000 55249 8 2013-08-30 00:00:00.000 55250 8 2013-08-30 00:00:00.000 55251 8 2013-08-30 00:00:00.000 55252 8 2013-08-30 00:00:00.000 55253 8 2013-08-30 00:00:00.000 SalesOrderID ProductID CarrierTrackingNumber OrderQt 55233 738 1590-499E-95 5 55233 792 1590-499E-95 5 55233 793 1590-499E-95 4 55233 794 1590-499E-95 4 55233 795 1590-499E-95 4 55233 796 1590-499E-95 5 55233 797 1590-499E-95 6 55233 798 1590-499E-95 2 55233 799 1590-499E-95 1 55233 800 1590-499E-95 1 55233 801 1590-499E-95 6 55233 835 1590-499E-95 6 55233 874 1590-499E-95 8 55233 875 1590-499E-95 8 55233 938 1590-499E-95 5 55233 939 1590-499E-95 5 55233 940 1590-499E-95 4 55233 973 1590-499E-95 5 55233 974 1590-499E-95 1 55233 975 1590-499E-95 1 Non-blocking
  • 24. 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. MergeNon-blocking
  • 25. MergeNon-blocking SELECT [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[OrderDate] FROM [Sales].[SalesOrderHeader] soh JOIN [Sales].[SalesOrderDetail] sod ON sod.[SalesOrderID] = soh.[SalesOrderID]
  • 26. MergeNon-blocking SalesOrderID RevisionNumber OrderDate 55233 8 2013-08-30 00:00:00.000 55234 8 2013-08-30 00:00:00.000 55235 8 2013-08-30 00:00:00.000 55236 8 2013-08-30 00:00:00.000 55237 8 2013-08-30 00:00:00.000 55238 8 2013-08-30 00:00:00.000 55239 8 2013-08-30 00:00:00.000 55240 8 2013-08-30 00:00:00.000 55241 8 2013-08-30 00:00:00.000 55242 8 2013-08-30 00:00:00.000 55243 8 2013-08-30 00:00:00.000 55244 8 2013-08-30 00:00:00.000 55245 8 2013-08-30 00:00:00.000 55246 8 2013-08-30 00:00:00.000 55247 8 2013-08-30 00:00:00.000 55248 8 2013-08-30 00:00:00.000 55249 8 2013-08-30 00:00:00.000 55250 8 2013-08-30 00:00:00.000 55251 8 2013-08-30 00:00:00.000 55252 8 2013-08-30 00:00:00.000 55253 8 2013-08-30 00:00:00.000 SalesOrderID ProductID CarrierTrackingNumber OrderQt 55233 738 1590-499E-95 5 55233 792 1590-499E-95 5 55233 793 1590-499E-95 4 55233 794 1590-499E-95 4 55233 795 1590-499E-95 4 55233 796 1590-499E-95 5 55233 797 1590-499E-95 6 55233 798 1590-499E-95 2 55233 799 1590-499E-95 1 55233 800 1590-499E-95 1 55233 801 1590-499E-95 6 55233 835 1590-499E-95 6 55233 874 1590-499E-95 8 55233 875 1590-499E-95 8 55233 938 1590-499E-95 5 55233 939 1590-499E-95 5 55233 940 1590-499E-95 4 55233 973 1590-499E-95 5 55233 974 1590-499E-95 1 55233 975 1590-499E-95 1
  • 27. 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.
  • 28. Hash MatchBlocking 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
  • 29. Hash MatchBlocking ProductID CarrierTrackingNumber Hash 707 4BC2-4C6D-83 -767544381 711 2AA4-4D12-9F -767515863 715 C811-4D40-80 -767499885 715 8FCD-4D55-8F -767496256 714 CC2F-4D47-8C -767488607 712 BE3B-4D30-A7 -767488106 707 9EBF-4C7E-82 -767471833 716 F78B-4D68-8E -767470049 712 8EBE-4D2C-AB -767459569 716 7DE5-4D74-A7 -767455808 715 46EF-4D44-A9 -767449380 711 9FC2-4D08-A7 -767447057 ProductID CarrierTrackingNumbe 736 2554-4F68-AB -767556491 717 9526-4D73-83 -767556433 715 CC2F-4D47-8C -767554143 715 2960-4D59-96 -767553412 722 9708-4E22-A4 -767551834 722 6F5C-4E3C-B5 -767549829 717 7E0A-4D6E-9E -767545458 707 4BC2-4C6D-83 -767544381 716 F108-4D76-8A -767543168 711 B900-4D0D-AF -767541067 711 67A0-4D10-87 -767539667 707 8441-4C6F-89 -767535798 Hash Table 1 Hash Table 2
  • 32. 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]
  • 33. 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)
  • 34. Parallelism Table 'SalesOrderDetail'. Scan count 18, logical reads 2490, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times: CPU time = 9593 ms, elapsed time = 2381 ms. Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'SalesOrderDetail'. Scan count 2, logical reads 2490, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read- ahead reads 0. SQL Server Execution Times: CPU time = 7941 ms, elapsed time = 8372 ms.
  • 36. 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]
  • 37. 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]
  • 38. Sort (spill) Operator used tempdb to spill data during execution with spill level 1 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]
  • 39. 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]
  • 40. Implicit Conversion SELECT [sod].[ProductID], [sod].[CarrierTrackingNumber], [sod].[UnitPrice], [sod].[OrderQty], [rowguid] FROM [Sales].[SalesOrderDetail] sod WHERE LEFT([sod].[rowguid],4) = N'FE10'
  • 42. Cool Tools/Products SQL Server Query Plan Analysis by Joe Sack
  • 44. Thank You! Mike Lawell Principal Consultant Twitter: @SQLDiver Blog: SQLServerAssociates.com LinkedIn: LinkedIn.com/in/MikeLawell Email: mike@sqlserverassociates.com
  • 45. Who Am I? Mike Lawell Mike Lawell Principal Consultant Twitter: @SQLDiver Blog: SQLServerAssociates.com LinkedIn: LinkedIn.com/in/MikeLawell

Editor's Notes

  • #9: Object Names, Data types, Aggregate Binding
  • #10: Is it in plan cache? Estimated plan(s) Costs per plan? Sent to Storage Engine for execution.
  • #11: Is did recompile get triggered? Over cost threshold for parallelism?
  • #14: Cardinality Estimation Model Version 120 (new model) 70 old model.
  • #15: Cardinality Estimation Model Version 120 (new model) 70 old model.
  • #18: 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.
  • #29: 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.
  • #30: Table results are inserted into a temporary table and columns hashed for each table then matched from the temporary table. It is a blocking process as it must populate the hash tables completely before it can match the hash values for output.
  • #38: Average is a count and sum
  • #39: Disabled statistics, loaded table with