Presentation is loading. Please wait.

Presentation is loading. Please wait.

Execution Plans for Mere Mortals Contact your Local or Virtual Chapter for their unique discount to SAVE $150! I’M SPEAKING JOIN ME AGAIN OCTOBER 27-30:

Similar presentations


Presentation on theme: "Execution Plans for Mere Mortals Contact your Local or Virtual Chapter for their unique discount to SAVE $150! I’M SPEAKING JOIN ME AGAIN OCTOBER 27-30:"— Presentation transcript:

1 Execution Plans for Mere Mortals Contact your Local or Virtual Chapter for their unique discount to SAVE $150! I’M SPEAKING JOIN ME AGAIN OCTOBER 27-30:

2 Execution Plans for Mere Mortals A beginners look at execution plans. Mike Lawell, Teammate, Linchpin People

3 Please silence cell phones 3

4 Agenda We will be taking a look at Graphical Execution Plans from a beginners perspective. The ride will include the following: We will be taking a look at Graphical Execution Plans from a beginners perspective. The ride will include the following: Execution Steps Execution Steps Execution Plan Basics Execution Plan Basics Basic Operators Basic Operators Join Operators Join Operators Other Operators Other Operators 4

5 EXECUTION Step by Step

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 Query Parsing 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 Output as Parse Tree to Algebrizer 7

8 Query Parsing SELECT [Name], [Number] FORM [Production].[Product] Incorrect syntax near 'Production'.

9 Query Parsing SELECT [Name], [Number] FROM [Production].[Product]

10 Execute Parallel/ Not Parallel Store in Plan Cache (*) Find/Create Plan Hash Checked in Plan Cache Aggregate Binding Resolve Data Types Name Resolution Plan Creation 10 3 45 6 12 Does Plan Exist? Algebrizer Query Optimizer Yes Recompile? No Storage Engine No Results Returned 7 Cost > Cost for Parallelism 8

11 Execute Parallel/ Not Parallel Store in Plan Cache (*) Find/Create Plan Hash Checked in Plan Cache Aggregate Binding Resolve Data Types Name Resolution Plan Creation 11 3 45 6 12 Does Plan Exist? Algebrizer Query Optimizer Yes Recompile? No Storage Engine No Results Returned 7 Cost > Cost for Parallelism 8 When a plan is found, good enough or optimal, then it is stored in cache (*). *If optimize for adhoc workloads is enabled, a stub is saved the first execution. If a recompile has been triggered, the process starts over. Is cost > cost for threshold? If it is, parallelize query. The algebrizer finds aggregate operations and performs aggregate binding. The algebrizer resolves the data types for the objects being accessed. The algebrizer resolves the names for objects (tables, columns, etc). Check the query hash against the plan cache to see if it exists If it doesn’t exist, use the query processor tree and statistics to determine execution plan generating multiple plans assigning cost (CPU, I/O) to each step and picks the best one.

12 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). NameUpdatedRowsRows SampledStepsAverage key lengthString IndexFilter ExpressionUnfiltered Rows _WA_Sys_00000003_3D7E1B63Nov 26 2014 11:26AM1000100019624YESNULL1000 RANGE_HI_KEYRANGE_ROWSEQ_ROWSDISTINCT_RANGE_ROWSAVG_RANGE_ROWS 002EE045-E300101 0169388E-8EC6161 031622B3-B683131 0424F840-4C23131 04C4FEAC-7C13131 Find/Create Plan 5

13 Cardinality Estimation There are multiple factors that can negatively impact the cardinality estimation process: 1. 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. 2.Cardinality Estimation Errors https://www.sqlskills.com/blogs/joe/cardinality-estimation-model-version/

14 Which cardinality version am I using?

15 EXECUTION PLAN BASICS Getting Started

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];

17 How to Read 17 1 3 2 4 5 6

18 BASIC OPERATORS The Meaty Morsels

19 Basic Operators 19 DML StatementsAccess MethodsOther Operators

20 JOIN OPERATORS Making it Happen

21 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 22 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 Nested Loop 23 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 Nested Loop

25 Non-blocking Nested Loop SalesOrderIDRevisionNumberOrderDate 5523382013-08-30 00:00:00.000 5523482013-08-30 00:00:00.000 5523582013-08-30 00:00:00.000 5523682013-08-30 00:00:00.000 5523782013-08-30 00:00:00.000 5523882013-08-30 00:00:00.000 5523982013-08-30 00:00:00.000 5524082013-08-30 00:00:00.000 5524182013-08-30 00:00:00.000 5524282013-08-30 00:00:00.000 5524382013-08-30 00:00:00.000 5524482013-08-30 00:00:00.000 5524582013-08-30 00:00:00.000 5524682013-08-30 00:00:00.000 5524782013-08-30 00:00:00.000 5524882013-08-30 00:00:00.000 5524982013-08-30 00:00:00.000 5525082013-08-30 00:00:00.000 5525182013-08-30 00:00:00.000 5525282013-08-30 00:00:00.000 5525382013-08-30 00:00:00.000 SalesOrderIDProductIDCarrierTrackingNumberOrderQty 552337381590-499E-955 552337921590-499E-955 552337931590-499E-954 552337941590-499E-954 552337951590-499E-954 552337961590-499E-955 552337971590-499E-956 552337981590-499E-952 552337991590-499E-951 552338001590-499E-951 552338011590-499E-956 552338351590-499E-956 552338741590-499E-958 552338751590-499E-958 552339381590-499E-955 552339391590-499E-955 552339401590-499E-954 552339731590-499E-955 552339741590-499E-951 552339751590-499E-951

26 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

27 Merge 27 SELECT [sod].[CarrierTrackingNumber], [sod].[OrderQty], [soh].[RevisionNumber], [soh].[OrderDate] FROM [Sales].[SalesOrderHeader] soh JOIN [Sales].[SalesOrderDetail] sod ON sod.[SalesOrderID] = soh.[SalesOrderID] Non-blocking

28 Merge SalesOrderIDRevisionNumberOrderDate 5523382013-08-30 00:00:00.000 5523482013-08-30 00:00:00.000 5523582013-08-30 00:00:00.000 5523682013-08-30 00:00:00.000 5523782013-08-30 00:00:00.000 5523882013-08-30 00:00:00.000 5523982013-08-30 00:00:00.000 5524082013-08-30 00:00:00.000 5524182013-08-30 00:00:00.000 5524282013-08-30 00:00:00.000 5524382013-08-30 00:00:00.000 5524482013-08-30 00:00:00.000 5524582013-08-30 00:00:00.000 5524682013-08-30 00:00:00.000 5524782013-08-30 00:00:00.000 5524882013-08-30 00:00:00.000 5524982013-08-30 00:00:00.000 5525082013-08-30 00:00:00.000 5525182013-08-30 00:00:00.000 5525282013-08-30 00:00:00.000 5525382013-08-30 00:00:00.000 SalesOrderIDProductIDCarrierTrackingNumberOrderQty 552337381590-499E-955 552337921590-499E-955 552337931590-499E-954 552337941590-499E-954 552337951590-499E-954 552337961590-499E-955 552337971590-499E-956 552337981590-499E-952 552337991590-499E-951 552338001590-499E-951 552338011590-499E-956 552338351590-499E-956 552338741590-499E-958 552338751590-499E-958 552339381590-499E-955 552339391590-499E-955 552339401590-499E-954 552339731590-499E-955 552339741590-499E-951 552339751590-499E-951 Non-blocking

29 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 30 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 Hash Match 31 ProductIDCarrierTrackingNumberHash 7074BC2-4C6D-83-767544381 7112AA4-4D12-9F-767515863 715C811-4D40-80-767499885 7158FCD-4D55-8F-767496256 714CC2F-4D47-8C-767488607 712BE3B-4D30-A7-767488106 7079EBF-4C7E-82-767471833 716F78B-4D68-8E-767470049 7128EBE-4D2C-AB-767459569 7167DE5-4D74-A7-767455808 71546EF-4D44-A9-767449380 7119FC2-4D08-A7-767447057 7256B7D-4E47-B5-767446438 714C811-4D40-80-767434349 ProductIDCarrierTrackingNumberHash 7362554-4F68-AB-767556491 7179526-4D73-83-767556433 715CC2F-4D47-8C-767554143 7152960-4D59-96-767553412 7229708-4E22-A4-767551834 7226F5C-4E3C-B5-767549829 7177E0A-4D6E-9E-767545458 7074BC2-4C6D-83-767544381 716F108-4D76-8A-767543168 711B900-4D0D-AF-767541067 71167A0-4D10-87-767539667 7078441-4C6F-89-767535798 739688B-4F92-AD-767532740 736EA8F-4F7A-AA-767532225 Hash Table 1Hash Table 2 Blocking * Extra columns from query do not appear in this visualization. Only the significant columns appear.

32 Fixed Hash Match

33 OTHER OPERATORS Deep Dive

34 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]

35 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)

36 Parallelism

37 Parallelism

38 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]

39 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]

40 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]

41 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]

42 Implicit Conversion SELECT [sod].[ProductID], [sod].[CarrierTrackingNumber], [sod].[UnitPrice], [sod].[OrderQty], [rowguid] FROM [Sales].[SalesOrderDetail] sod WHERE LEFT([sod].[rowguid],4) = N'FE10'

43 Cool Tools/Products SQL Server Query Plan Analysis by Joe Sack

44 Resources http://www.red-gate.com/community/books/

45 Mike Lawell Principal Consultant Twitter:@SQLDiver Blog:SQLServerAssociates.com LinkedIn:LinkedIn.com/in/MikeLawell

46 Explore Everything PASS Has to Offer 46 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 COMMUNITYBUSINESS ANALYTICS TRAINING SESSION RECORDINGSPASS NEWSLETTER

47 Properties

48

49

50 Palette 50 PRIMARY PALETTESECONDARY PALETTE

51 Titles are set 36 Segoe UI, maximum 2 lines, ideally 1 line Heading One Style, 28pt Body content, 18pt Segoe UI (gray) Heading Two Style, 24pt Body content, 18pt Segoe UI (gray) HEADING THREE STYLE, 16pt, BOLD, ALL CAPS Body content, 18pt Segoe UI (gray) 51

52 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.

53 Query Optimizer 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 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 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. 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. Once an acceptable estimated plan is found it is stored in the plan cache then sent to the query execution.

54 Query Execution Storage Engine The storage engine determines if a recompile was triggered causing a change in the estimated execution plan. The storage engine determines if a recompile was triggered causing a change in the estimated execution plan. SQL Server determines based upon cost whether it exceeds the threshold for parallelism changing the estimated plan for parallelism. SQL Server determines based upon cost whether it exceeds the threshold for parallelism changing the estimated plan for parallelism. Statistics that have changed causing a change in the estimated plan. Statistics that have changed causing a change in the estimated plan. SQL Server returns the results.


Download ppt "Execution Plans for Mere Mortals Contact your Local or Virtual Chapter for their unique discount to SAVE $150! I’M SPEAKING JOIN ME AGAIN OCTOBER 27-30:"

Similar presentations


Ads by Google