TIP Before enabling SHOWPLAN_TEXT or SHOWPLAN_ALL options in a Query Editor session in SSMS, be sure to disable the Include Actual Execution Plan option; otherwise, the SHOWPLAN options
Trang 1TIP
Unlike the graphical execution plans, SSMS does not provide a way to save the client
statistics Fortunately, the statistics are displayed using a standard grid control You
can right-click the client statistics and choose Select All Then you right-click and select
Copy You can then paste the information into a spreadsheet program such as Excel,
which allows you to save the information or perform further statistical analysis on it
In addition to the graphical execution plans available in SSMS, SQL Server 2008 provides
three SET SHOWPLAN options to display the execution plan information in a text or XML
format These options are SET SHOWPLAN_TEXT, SET SHOWPLAN_ALL, and SET SHOWPLAN_XML
When one of these options is enabled, SQL Server returns the execution plan generated
for the query, but no results are returned because the query is not executed It’s similar to
the Display Estimated Execution Plan option in SSMS
You can turn on the textual execution plan output in a couple of ways One way is to
issue the SET SHOWPLAN_TEXT ON, SET SHOWPLAN_ALL ON, or SET SHOWPLAN_XML ON
command directly in the SSMS query window These commands must be executed in a
separate batch by themselves before running a query
TIP
Before enabling SHOWPLAN_TEXT or SHOWPLAN_ALL options in a Query Editor session in
SSMS, be sure to disable the Include Actual Execution Plan option; otherwise, the
SHOWPLAN options will have no effect
SHOWPLAN_TEXT
Typing the following command in an SSMS query window turns on the SHOWPLAN_TEXT
option:
SET SHOWPLAN_TEXT ON
GO
Setting this option causes the textual showplan output to be displayed in the results panel
but does not execute the query You can also enable the SHOWPLAN_TEXT option by
choos-ing the Query Options item from the Query menu In the Query Options dialog, you click
the Advanced item and check the SET SHOWPLAN_TEXT option
The SHOWPLAN_TEXT option displays a textual representation of the execution plan Listing
36.3 shows an example for a simple inner join query
TIP
When you are displaying the SHOWPLAN_TEXT information in SSMS, it is usually easiest
to view if you configure SSMS to return results to text rather than as a grid
Trang 2LISTING 36.3 An Example of SHOWPLAN_TEXT Output
set showplan_text on
go
select st.stor_name, ord_date, qty
from stores st join sales_noclust s on st.stor_id = s.stor_id
where st.stor_id between ‘B100’ and ‘B199’
go
StmtText
-select st.stor_name, ord_date, qty from stores st join sales_noclust s on st.stor_id = s.stor_id where st.stor_id between ‘B100’ and ‘B199’ (1 row(s) affected) StmtText
-| Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1002], [Expr1006]) WITH
UNORDERED PREFETCH)
| Nested Loops(Inner Join, OUTER REFERENCES:([st].[stor_id]))
| | Clustered Index
Seek(OBJECT:([bigpubs2008].[dbo].[stores].[UPK_storeid]
AS [st]), SEEK:([st].[stor_id] >= ‘B100’ AND [st].[stor_id] <= ‘B199’)
ORDERED FORWARD)
| | Index Seek(OBJECT:([bigpubs2008].[dbo].[sales_noclust].[idx1] AS
[s]), SEEK:([s].[stor_id]=[bigpubs2008].[dbo].[stores].[stor_id] as
[st].[stor_id]), WHERE:([bigpubs2008].[dbo].[sales_noclust].[stor_id] as
[s].[stor_id]>=’B100’ AND [bigpubs
| RID Lookup(OBJECT:([bigpubs2008].[dbo].[sales_noclust] AS [s]),
SEEK:([Bmk1002]=[Bmk1002]) LOOKUP ORDERED FORWARD)
(5 row(s) affected)
The output is read from right to left, similarly to the graphical execution plan Each line
represents a physical/logical operator The text displayed matches the logical and physical
operator names displayed in the graphical execution plan If you can read the graphical
query plan, you should have no trouble reading the SHOWPLAN_TEXT output
In the example in Listing 36.3, SQL Server performs a clustered index seek on the stores
table, using the UPK_storeid index, and a nonclustered index seek on sales_noclust,
using index idx1 The inputs are combined using a nested loop join Finally, a RID lookup
is performed to retrieve the ord_date and qty information from the sales_noclust table
Trang 3When the SHOWPLAN_TEXT option is set to ON, execution plan information about all
subse-quent SQL Server 2008 statements is returned until the option is set to OFF Also, all
subse-quent commands are optimized but not executed To turn off the textual showplan output
and allow execution of commands again, type the following command:
SET SHOWPLAN_TEXT OFF
GO
TIP
To switch from one SET SHOWPLAN option to another, remember that no commands are
executed until the SET SHOWPLAN option is turned off This includes setting the SET
SHOWPLAN options For example, to switch from SHOWPLAN_TEXT to either
SHOWPLAN_ALL or SHOWPLAN_XML, you have to turn off SHOWPLAN_TEXT first with the SET
SHOWPLAN_TEXT OFF command
SHOWPLAN_ALL
The SHOWPLAN_ALL option displays the same textual execution plan information as the
SHOWPLAN_TEXT option, and it also provides additional columns of output for each row of
textual showplan output These columns provide much of the same information available
in the graphical execution ToolTips, and the column headings correspond to the ToolTip
items listed in the “Execution Plan ToolTips” section, earlier in this chapter Table 36.1
describes the information provided in the data columns returned by the SHOWPLAN_ALL
option
TABLE 36.1 Data Columns Returned by SHOWPLAN_ALL
Column Name Description
StmtText The text of the T-SQL statement and also each of the physical
operators in the execution plan (It may optionally also contain the logical operators.)
StmtId The number of the statement in the current batch
NodeId The ID of the node in the current query
Parent The node ID of the parent operator for the current operator
PhysicalOp Physical operator description for the current node
LogicalOp Logical operator description for the current node
Argument Supplemental information about the operation being performed
DefinedValues A comma-separated list of values introduced by this operator These may
be either computed expressions present in the current query or internal values introduced by the query processor to be able to process this query
Trang 4TIP
When you are displaying the SHOWPLAN_ALL information in SSMS, it is usually easiest
to view if you configure SSMS to return results to grid rather than as text
SHOWPLAN_XML
When SET SHOWPLAN_XML is set to ON, SQL Server does not execute the query but returns
execution information for each T-SQL batch as an XML document The execution plan
information for each T-SQL batch is contained in a single XML document Each XML
document contains the text of the statements in the batch, followed by the details of the
execution steps and operators The document includes the estimated costs, numbers of
rows, indexes used, join order, and types of operators performed
The SHOWPLAN_XML option generates the same XML output as the Show Estimated
Execution Plan option in SSMS In essence, you are looking at the same information, just
without the pretty pictures As a matter of fact, you can save the output from the
SHOWPLAN_XML option to a file and open it back into SSMS as a SQL plan file The
recom-mended approach is to configure the query window to return results to a grid If you
return the results as text or to a file, the maximum output size for a character column in
TABLE 36.1 Data Columns Returned by SHOWPLAN_ALL
Column Name Description
EstimateRows Estimated number of rows of output produced by the operator
EstimateIO Estimated I/O cost for the operator
EstimateCPU Estimated CPU cost for the operator
AvgRowSize Estimated average row size (in bytes) of the row being passed through
the operator
TotalSubtreeCost Estimated (cumulative) cost of this operation and all child operations
OutputList A comma-separated list of columns being projected by the current
operation
Warnings A comma-separated list of warning messages relating to the current
operation (for example, missing statistics)
Type The type of node (either PLAN_ROW or the type of T-SQL statement)
Parallel Whether the operator is running in parallel (1) or not (0)
EstimateExecutions Estimated number of times this operator will be executed while running
the current query
Trang 5SSMS is 8,192 bytes If the XML document exceeds this length, it is truncated and does
not load correctly In the grid results, the maximum size of XML data is 2MB
After you run the query and generate the grid results, you can right-click on the result row
and choose the Save Results As option to specify the file to save the results to If all goes
well, you end up with a sqlplan file that you can then load back into SSMS for further
analysis at a later date
NOTE
The document containing the XML schema for the SET SHOWPLAN_XML output is available
in the same directory as the SQL Server installation, which by default is C:\Program
Files\Microsoft SQL Server\100\Tools\Binn\schemas\sqlserver\2004\07\
showplan\showplanxml.xsd
Dynamic management views (DMVs) can return server state information that can be used
to monitor and diagnose database engine issues and help tune performance The
sys.dm_exec_query_plan DMV returns the showplan information for a T-SQL batch whose
query execution plan resides in the plan cache This can be any SQL batch, not just the
batch executed by the current user session The sys.dm_exec_query_plan DMV also
provides the capability to retrieve the execution plan for currently long-running processes
to help diagnose why they may be running slowly
The showplan information provided by sys.dm_exec_query_plan is returned in a column
called query_plan, which is of the xml data type This column provides the same
informa-tion as SET SHOWPLAN XML The syntax of sys.dm_exec_query_plan is
sys.dm_exec_query_plan ( plan_handle )
In SQL Server 2008, the query plans for various types of T-SQL batches are cached in an
area of memory called the plan cache Each cached query plan is identified by a unique
identifier called a plan handle To view the showplan for one of these batches, you need to
provide the plan handle for the batch to the sys.dm_exec_query_plan DMV
The tricky part about using sys.dm_exec_query_plan is determining the plan handle to
use First, you need to determine the SPID for the process with the long-running query
This is usually accomplished using sp_who2 or via the SSMS Activity Monitor
When you have the SPID, you can use the sys.dm_exec_requests DMV to obtain the plan
handle (assume in this case that the SPID is 58):
select plan_handle from sys.dm_exec_requests where session_id = 58
go
Trang 6plan_handle
-0x06000A00E96E6D2CB8A1F505000000000000000000000000
When you have the plan handle, you can pass it on to the sys.dm_exec_query_plan DMV
to return the query plan:
SELECT query_plan
FROM sys.dm_exec_query_plan (0x06000A00E96E6D2CB8A1F505000000000000000000000000)
Alternatively, to prevent having to copy and paste the plan handle from the
sys.dm_exec_requests query into the query against sys.dm_exec_query_plan, you can use
the CROSS APPLY clause, as in the following query:
SELECT query_plan FROM sys.dm_exec_requests cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle)
where cp.session_id = 58
If you return the results to grid, you can right-click the data in the query_plan column
and save it to a file, which can then be loaded into SSMS to view the graphical execution
plan, just like the output from the SET SHOWPLAN_XML option
To return the query plan for all currently running T-SQL batches, you can run the following:
SELECT query_plan FROM sys.dm_exec_requests cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle)
In addition to returning the query plans for the currently running T-SQL batches, SQL
Server 2008 also provides the sys.dm_exec_query_stats and sys.dm_exec_cached_plans
DMVs The sys.dm_exec_cached_plans DMV can be used to return information about all
query plans currently residing in the plan cache For example, to retrieve a snapshot of all
query plans residing in the plan cache, you use the CROSS APPLY operator to pass the plan
handles from sys.dm_exec_cached_plans to sys.dm_exec_query_plan, as follows:
SELECT * FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle)
To retrieve a snapshot of all query plans that currently reside in the plan cache for which
the server has gathered statistics, use the CROSS APPLY operator to pass the plan handles
from sys.dm_exec_query_stats to sys.dm_exec_query_plan as follows:
SELECT * FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle)
Because sys.dm_exec_query_plan provides the capability to view the query plan for any
session, a user must be a member of the sysadmin fixed server role or have the VIEW
SERVER STATE permission on the server to invoke it
Trang 7NOTE
The SET SHOWPLAN_ALL and SET SHOWPLAN_TEXT options are deprecated features and
may be removed in a future version of SQL Server It is recommended that you switch
to using the SET SHOWPLAN_XML option instead
Query Statistics
In addition to the new dynamic management objects, SQL Server 2008 still provides the
SET STATISTICS IO and SET STATISTICS TIME options, which display the actual logical
and physical page reads incurred by a query and the CPU and elapsed time, respectively
These two SET options return actual execution statistics, as opposed to the estimates
returned by SSMS and the SHOWPLAN options discussed previously These two tools can be
invaluable for determining the actual cost of a query
In addition to the IO and TIME statistics, SQL Server also provides the SET STATISTICS
PROFILE and SET STATISTICS XML options These options are provided to display
execu-tion plan informaexecu-tion while still allowing the query to run
STATISTICS IO
You can set the STATISTICS IO option for individual user sessions, and you can turn it on
in an SSMS query window by typing the following:
SET STATISTICS IO ON
GO
You can also set this option for the query session in SSMS by choosing the Options item
in the Query menu In the Query Options dialog, click the Advanced item and check the
SET STATISTICS IO check box, as shown in Figure 36.14
FIGURE 36.14 Enabling the STATISTICS IO option in SSMS.
Trang 8The STATISTICS IO option displays the scan count (that is, the number of iterations), the
logical reads (from cached data), the physical reads (from physical storage), and the
read-ahead reads
Listing 36.4 displays the STATISTICS IO output for the same query executed in Listing
36.3 (Note that the result set has been deleted to save space.)
LISTING 36.4 An Example of STATISTICS IO Output
set statistics io on
go
select st.stor_name, ord_date, qty
from stores st join sales_noclust s on st.stor_id = s.stor_id
where st.stor_id between ‘B100’ and ‘B199’
go
output deleted
(1077 row(s) affected)
Table ‘sales_noclust’ Scan count 100, logical reads 1383, physical reads 5,
read-ahead reads 8, lob logical reads 0, lob physical reads 0,
lob read-ahead reads 0
Table ‘stores’ Scan count 1, logical reads 3, physical reads 0,
read-ahead reads 0, lob logical reads 0, lob physical reads 0,
lob read-ahead reads 0
Scan Count
The scan count value indicates the number of times the corresponding table was accessed
during query execution The outer table of a nested loop join typically has a scan count of
1 The scan count for the inner tables typically reflects the number of times the inner
table is searched, which is usually the same as the number of qualifying rows in the outer
table The number of logical reads for the inner table is equal to the scan count multiplied
by the number of pages per lookup for each scan Note that the scan count for the inner
table might sometimes be only 1 for a nested join if SQL Server copies the needed rows
from the inner table into a work table in cache memory and reads from the work table for
subsequent iterations (for example, if it uses the Table Spool operation) The scan count
for hash joins and merge joins is typically 1 for both tables involved in the join, but the
logical reads for these types of joins are usually substantially higher
Logical Reads
The logical reads value indicates the total number of page accesses necessary to process
the query Every page is read from cache memory, even if it first has to be read from disk
Every physical read always has a corresponding logical read, so the number of physical
reads will never exceed the number of logical reads Because the same page might be
Trang 9accessed multiple times, the number of logical reads for a table could exceed the total
number of pages in the table
Physical Reads
The physical reads value indicates the actual number of pages read from disk The value
for physical reads can vary greatly and should decrease, or drop to zero, with subsequent
executions of the query because the data will be loaded into the data cache by the first
execution The number of physical reads will also be lowered by pages brought into
memory by the read-ahead mechanism
Read-Ahead Reads
The read-ahead reads value indicates the number of pages read into cache memory using
the read-ahead mechanism while the query was processed Pages read by the read-ahead
mechanism will not necessarily be used by the query When a page read by the read-ahead
mechanism is accessed by the query, it counts as a logical read, but not as a physical read
The read-ahead mechanism can be thought of as an optimistic form of physical I/O,
reading the pages into cache memory that it expects the query will need before the query
needs them When you are scanning a table or index, the table’s index allocation map
pages (IAMs) are looked at to determine which extents belong to the object An extent
consists of eight data pages The eight pages in the extent are read with a single read, and
the extents are read in the order that they are stored on disk If the table is spread across
multiple files, the read-ahead mechanism attempts parallel reads from up to eight files at a
time instead of sequentially reading from the files
LOB Reads
If the query retrieves text, ntext, image, or large value type (varchar(max), nvarchar(max),
varbinary(max)) data, the lob logical reads, lob physical reads, and lob read-ahead
reads values provide the logical, physical, and read-ahead read statistics for the large
object (LOB) I/Os
Analyzing STATISTICS IO Output
The output shown in Listing 36.4 indicates that the sales_noclust table was scanned 100
times, with 5 physical reads (that is, 5 physical I/Os were performed) The stores table
was scanned once, with all reads coming from cache (physical reads = 0)
You can use the STATISTICS IO option to evaluate the effectiveness of the size of the data
cache and to evaluate, over time, how long a table will stay in cache The lack of physical
reads is a good sign, indicating that memory is sufficient to keep the data in cache If you
keep seeing many physical reads when you are analyzing and testing your queries, you
might want to consider adding more memory to the server to improve the cache hit ratio
You can estimate the cache hit ratio for a query by using the following formula:
Cache hit ratio = (Logical reads – Physical reads) / Logical reads
The number of physical reads appears lower than it actually is if pages are preloaded by
read-ahead activity Because read-ahead reads lower the physical read count, they give the
indication of a good cache hit ratio, when in actuality, the data is still being physically
Trang 10read from disk The system could still benefit from more memory so that the data remains
in cache and the number of read-ahead reads is reduced STATISTICS IO is generally more
useful for evaluating individual query performance than for evaluating overall cache hit
ratio The pages that reside and remain in memory for subsequent executions are
deter-mined by the data pages being accessed by other queries executing at the same time and
the number of data pages being accessed by the other queries If no other activity is
occur-ring, you are likely to see no physical reads for subsequent executions of the query if the
amount of data being accessed fits in the available cache memory Likewise, if the same
data is being accessed by multiple queries, the data tends to stay in cache, and the number
of physical reads for subsequent executions tends to be low However, if other queries
executing at the same time are accessing large volumes of data from different tables or
ranges of values, the data needed for the query you are testing might end up being flushed
from cache, and the physical I/Os will increase Depending on the other ongoing SQL
Server activity, the physical reads you see displayed by STATISTICS IO can be inconsistent
When you are evaluating individual query performance, examining the logical reads value
is usually more helpful because the information is consistent across all executions,
regard-less of other SQL Server activity Generally speaking, the queries with the fewest logical
reads are the fastest queries If you want to monitor the overall cache hit ratio for all SQL
Server activity to evaluate the SQL Server memory configuration, use the Performance
Monitor, which is discussed in Chapter 39, “Monitoring SQL Server Performance.”
STATISTICS TIME
You can set the STATISTICS TIME option for individual user sessions In an SSMS query
window, you type the following:
SET STATISTICS TIME ON
You can also set this option for the query session in SSMS by choosing the Options item
in the Query menu In the Query Options dialog, you click the Advanced item and check
the SET STATISTICS TIME check box
The STATISTICS TIME option displays the total CPU and elapsed time that it takes to
actu-ally execute a query The STATISTICS TIME output for the query in Listing 36.3 returns
the output shown in Listing 36.5 (Again, the data rows returned have been deleted to
save space.)
LISTING 36.5 An Example of STATISTICS TIME Output
set statistics io on
set statistics time on
go
select st.stor_name, ord_date, qty
from stores st join sales_noclust s on st.stor_id = s.stor_id