Professional Documents
Culture Documents
http://sqlserverpedia.com/wiki/Examining_Query_Execution_Plans
SQLServerPedia
Your community knowledge base
Wiki Architecture & Configuration Business Intelligence (SSAS, SSIS, SSRS) Database Administration Monitoring SQL Servers Performance Tuning SQL Azure SQL Server Links SQL Server Tutorials Transact SQL Coding Techniques Transact SQL Coding and Naming Standards Transact SQL Code Library How to Write and Edit Articles Pulse Blog Professional Development Database Design Podcasts Site Updates Syndicate Your SQL Server Blog Project Lucy Podcasts Twitter Contributors Log in
From SQLServerPedia
Jump to: navigation, search See Also: Main_Page - Monitoring & Tuning - Tuning Tools - SQL Server Query Optimizer Several ways exist to generate an execution plan in SQL Server. First, and most frequently used, are the graphical execution plans. These are followed by XML execution plans and plain text execution plans.
Contents
[hide] 1 Graphical Execution Plans 1.1 SQL Server 2005/2008 1.1.1 Estimated Execution Plan 1.1.2 Actual Execution Plan 1.2 Execution Plan Example 1.3 SQL Server 2000 2 Text Execution Plans 3 Author Credits 4 Related Reading
1 of 4
1/11/2013 10:07 PM
http://sqlserverpedia.com/wiki/Examining_Query_Execution_Plans
After the query executes, the actual execution plan will be available in a different tab in the results pane of the query window.
This generates the following execution plan: Starting at the right and the top you see an Index Seek (NonClustered) against the index named [SalesOrderHeader].[IX_SalesOrderHeader_CustomerId]. This feeds data out to a Nested Loop (Inner Join). Working down you can see a Key Lookup (Clustered) operation against the PK_SalesOrderHeader_SalesOrderID. This is a classic key lookup, or what used to be called, a bookmark lookup. More on that later. You can see that the data feeds back up to the Nested Loop and then that feeds on down to another Nested Loop operator. Below that is a Clustered Index Seek (Clustered) against the [PK_SalesOrderDetail_SalesOrderId] primary key. Finally the data flow goes out to the SELECT operator. That's the basic information available within the execution plan. Lots more detail is also available. Hover with the mouse over one of the operators and you will get a tool tip, different for each operation type, showing some of the detail behind the operator. Displayed below is the tool tip for the Key Lookup operator:
At the very top of the tool tip is a description of the operator. In this case, "Uses a supplied clustering key to lookup on a table that has a clustered index." Most operators will include this description, telling you what the operator does within the execution plan. After that, most operations will have a varying number, and type, of fields within the tool tip, supplying different kind of information. An example of one of the common fields is Estimated Operator Cost. You'll see this in most tool tips for most operators. A piece of information that is specific to this operator (although not unique to this operator) is the Seek Predicate information at the bottom of the tool tip. But the most interesting piece of information for the Key Lookup operator is that it exists within this execution plan. It exists because, while the index on CustomerID is sufficient to get a specific set of rows returned to the application, all the columns needed are not contained on the index. Because the data is stored on the clustered index, and additional set of seeks are required to retrieve the data, which is joined with the information retrieved from the index on CustomerID through the Nested Loop join operation. To see even more information about the operators in the execution plan, right click an operator and select "Properties" from the drop down menu. This will open a complete properties sheet. Much of the data on the properties sheet is the same as that available in the Tool Tip, but even more is on display in the property sheet.
Resulting message:
Table 'authors'. Scan count 1, logical reads 138, physical reads 0, read-ahead reads 0.
SET NOEXEC ON will compile the query but will not execute it. This is helpful if you are testing a query that might take a long time. Instead of running a query each time you make changes to it, you might wish to examine the execution plan first.
2 of 4
1/11/2013 10:07 PM
http://sqlserverpedia.com/wiki/Examining_Query_Execution_Plans
SET STATISTICS TIME ON will inform you about the CPU time used and SQL Server time used to execute a particular query, for example:
SET STATISTICS time ON GO SELECT * FROM authors
Resulting messages:
Execution Times: 0 ms, elapsed time = 0 ms. parse and compile time: 0 ms, elapsed time = 0 ms. parse and compile time: 0 ms, elapsed time = 0 ms. Execution Times: 70 ms, elapsed time = 444 ms.
This output might be somewhat confusing in the beginning. The first statement refers to the time it took to execute the SET STATISTICS TIME ON statement - which is too small to measure. The second and third statement inform us of parse and compilation time for two statements: GO and SELECT * FROM authors. The statement in bold is the one we are most interested in: that is the actual time spent executing SELECT * FROM authors command.
SET SHOWPLAN_ALL ON will give you detailed information about the execution plan. The output of SHOWPLAN_ALL is not straightforward, however, understanding it give you the opportunity to know what is going on "behind the scenes". The following table describes the output of SHOWPLAN: Column Name StmtText StmtID NodeID Parent Node PhysicalOP LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel Number of the statements issued before the current statement in the current connection Node ID in the query ID for the parent step of the current node This is the physical implementation of the algorithm chosen by the query optimizer. If the row type is not plan_rows then this column is NULL Logical implementation of the algorithm chosen by the query optimizer. If the row type is not plan_rows then this column is NULL Provides additional information about the physical operation. For instance if a clustered index is being scanned this column will show the name of the index as well as index keys. This column contains a comma-separated list of columns defined in the query, or the list of internal values examined by the query optimizer The number of rows affected by the query Estimated IO for the operation mentioned in this row Estimated CPU usage for the operation mentioned in this row Average row size in bytes passed by this operation Estimated cost of this operation as well as all child operations List of the columns in the result set This column contains a coma-separated list of warnings that pertain to the current operation. For instance it might warn you that the statistics on a particular index being queried are out of date For the statements referenced in the query this column will contain the appropriate Transact-SQL command type (such as SELECT or UPDATE). For the rows that show the actual execution plan this column contains plan_row. If this column contains 1 than an operation is running in parallel Description This column either repeats the submitted query (in which case it's not very useful) or contains the physical and logical operations included in the query execution plan
EstimateExecutions Estimated number this operation will have to be executed for satisfying the current query Perhaps the most useful column out of the entire SHOWPLAN_ALL output is the StmtText, which tells you about the type of operation performed, whether it is a table scan, clustered or non-clustered index scan, etc. Most of this information is repeated again in PhysicalOp, LogicalOp and Argument columns, whichever is appropriate. Another column to watch is the Warnings - it might give you a clue to why your query isn't performing up to your expectations. Usually a warning might state that statistics are out of date or a join predicate is missing.
Author Credits
This article was originally written by Grant Fritchey.
Grant Fritchey Grant Fritchey works for FM Global, an industry-leading engineering and insurance company, as a principal DBA. He's done development of large-scale applications in languages such as VB, C#, and Java. He has worked with SQL Server since version 6.0. He has worked in finance and consulting and for three failed dot coms. He is the author of Dissecting SQL Server Execution Plans (Simple Talk Publishing, 2008) and SQL Server 2008 Performance Tuning Distilled (Apress, 2009). His online presences include: Blog - http://scarydba.wordpress.com/ Twitter - http://twitter.com/GFritchey
Related Reading
For more information about how to read query execution plans, check out these articles and blog posts: Wiki Article: Compiling an Execution Plan Wiki Article: Query Optimizer Overview Grant Fritchey on How Views Work in Execution Plans Grant Fritchey on the Three Kinds of Execution Plans Retrieved from "http://sqlserverpedia.com/wiki/Examining_Query_Execution_Plans" Editor In Chief
Richard Douglas
Richard Douglas is a SQL Server consultant for Quest Software in the UK covering a range of SQL Server products both in a pre and post sales capacity. Richard is often asked to come on site and perform server health checks to ensure systems are running optimally and to provide valuable feedback on problem areas. Read More Subscribe
3 of 4
1/11/2013 10:07 PM
http://sqlserverpedia.com/wiki/Examining_Query_Execution_Plans
RSS Top Searches SQL Server Date SQL Server Download SQL Server Functions SQL Server Management SQL Server Service SQL Server Tutorial Database Hosting Database Transaction
Powered by MediaWiki | 2012 Dell Inc., ALL RIGHTS RESERVED. | Privacy Policy | Terms of Use | Contact Us | Follow Us on Twitter
4 of 4
1/11/2013 10:07 PM