You are on page 1of 3

Join Beginner Tutorials DBA T-SQL Analytics Cloud Tools

Join Search
MSSQLTips

SQL Server Query Tuning with Statistics Time and Statistics


IO

By: Eric Blinn | Updated: 2020-09-30 | Comments | Related: More > Performance Tuning

Problem
I am working to improve the performance of a piece of SQL Server T-SQL code and I'm just not sure much the changes I am making are
helping or hurting. I need to be able to accurately track and report the performance improvement of my code changes.

Solution
The obvious answer is to look at the SQL Server query execution time, but that alone isn't always enough to determine that there is or
isn't an improvement – or if that new index is helping. If the query was already finishing in a second or 2 that just isn't enough precision to
determine if there is improvement. There are other things like caching and parallelism that can cause query execution time to be a
misleading statistic.

This tip will look at how to analyze query executions to determine how many system resources were used and how long the query took to
execute with far more precision than the query execution timer in SSMS so that a more definitive answer can be determined about
whether – and to what extent – query optimization was changed.

All of the demos in this tip will use the WideWorldImporters sample database which can be downloaded from here.

Measuring SQL Server query execution time with precision


Consider this query and execution.

SELECT *
FROM [WideWorldImporters].[Sales].[Invoices]
WHERE InvoiceDate='2014-03-15';

Recommended Reading
How to find out how much CPU a SQL Server
process is really using

Different Ways to Flush or Clear SQL Server


Cache

Optimize Moving SQL Server Data From One


Table to Another Table

UPDATE Statement Performance in SQL


Executing this query reports an execution time of 00:00:00 on this author's laptop. It seems unlikely that improving the speed of this Server
query will be useful as it is already running in less than 1 second. But what if this query runs 1,000x per second? Such occurrences are
Fastest way to Delete Large Number of
not uncommon in SQL Server OLTP workloads. How can an improvement be measured against 0? Records in SQL Server

The answer is that SQL Server offers a method to get execution times measured at the millisecond level which is 1000x more precise
than the timer on the bottom right of the query results pane in SSMS. The method is called STATISTICS TIME and can be enabled in one
of 2 ways.

In SSMS the setting can be enabled on the session by right-clicking white space in the query pane and choosing query options. It's all
the way at the bottom of the context menu. When the menu comes up choose "Advanced" on the left then check the box next to SET
STATISTICS TIME.

The best part about this method is that it is not limited to SSMS connections. This feature can be enabled on SSMS or any SQL Server
session by running this simple command.

SET STATISTICS TIME ON;

Now that the feature is enabled the query can be executed again and it will include additional output. The output of STATISTICS TIME
can be found on the messages tab in SSMS. To read this information in other applications the connection must be able to read the
InfoMessage event. It can be read in PowerShell by using the - verbose option of the invoke-sqlcmd cmdlet. The output from the
messages tab of SSMS is below.

Focus on the "SQL Server Execution Times:" section. The output shows that this query executed in 19 milliseconds. Running it
repeatedly showed numbers between 12 and 30 milliseconds on this laptop. With this level of precision measuring improvement will be
far easier.

Measuring SQL Server resource usage for a query


SQL Server offers a method to measure the resources used by the query. This feature is called STATISTICS IO and it is enabled and
used very similarly to STATISTICS TIME. Looking at the screenshot above the checkbox for STATISTICS TIME is immediately beneath
the highlighted checkbox. It has a similar query also.

SET STATISTICS TIME ON

This feature and the prior feature can be enabled at the same time using this query.

SET STATISTICS TIME,IO ON;

Enable the feature and then execute the same query for a 3rd time. Now there will be more output on the Messages tab.
enter business email Join

There will be one new row in the output for every table referenced in the query. Since this query only touches one table, there is only one
new row listed. It shows that the table 'Invoices' was queried and there is a lot of information on the row -- more than the screenshot even
includes. Focus should be placed on the "logical reads" section. This statistic shows the number of 8kb data pages that were read from
this table in total. The "physical reads" section shows how many of those reads were taken directly from disk. Since this reports a zero
that indicates all pages were found in the buffer pool and were read from memory.

Note that the execution time result remains since both features are enabled. The execution time output also includes the CPU time used
by the query. This is another great metric to watch when working to improve the query.

When combined, the CPU time, amount of data pages read (from disk or memory), and execution time measured to the millisecond
provide a wonderful baseline from which to compare future executions for performance improvement.

Comparing multiple SQL Server query executions


SSMS offers a tool that allows the user to compare multiple query executions and easily compare the performance of them. This feature
is called Client Statistics. It can be enabled in one of 3 ways – a button, a keyboard shortcut, or a context menu. The button is shown in
the screenshot below. The keyboard shortcut is Shift+Alt+S. Finally, it can be found near the bottom of the context menu of the query
text pane labeled "Include Client Statistics".

Running the sample query for the 4th time now includes a 3rd tab in the output. This table is labeled "Client Statistics". For the purposes
of this demo, the query was run a total of 3 more times after the client statistics were included.

The output is really great! It shows the execution time along with some useful statistics for each of the 3 new executions so that they can
be compared. The most useful line for this demo is the "Wait time on server replies" as this is the number of milliseconds that were
spent waiting for SQL Server to execute the query. Nothing was changed between executions so most of the values are the same or very
similar. As changes are made to the query or to the schema of the database the query can be executed again and the values compared
to see if there is an improvement or not.

Improving SQL Server query execution


The sample query that has been run during this tip queries against the column InvoiceDate which is not indexed. The query below will
create an index on the column InvoiceDate of the Sales.invoices table. For this demo the index creation will be done in a different
session than the one used for testing thus far.

CREATE NONCLUSTERED INDEX MAKE_ME_FASTER ON [Sales].[Invoices]([InvoiceDate])

Now that the index has been created the sample query can be run one final time. STATISTICS TIME, STATISTICS IO, and Client
Statistics should all still be enabled. For the purpose of this demo, the query was run 3 more times to better show the pattern.

The first values checked are those from STATISTICS TIME and STATISTICS IO. This output shows that after the index was created the
execution time dropped to below 1 ms from a value between 12 and 30 as seen above. The number of pages read dropped by over
99% from 6,558 to 2 and the CPU time dropped from 16ms to under 1ms. This proves that the index creation definitely helped the query
in a significant way.

Next, the output from Client Statistics should be reviewed. The screenshot below shows 6 executions total. 3 came before the index
was created and 3 after.

The output shows that the 3 executions before the index were created took 10, 7, and 4 milliseconds respectively. After the index was
created the execution times dropped to 4, 0, and 1 millisecond(s) each. This further confirms that the query is running much faster and
doesn't require the programmer write down or remember any previous execution times.
Next Steps
Check out this Performance Tuning Tutorial
Get more detail on STATISTICS TIME and IO

Last Updated: 2020-09-30

About the author


Eric Blinn is the Sr. Data Architect for Squire Patton Related Resources
Boggs. He is also a SQL author and PASS Local Group More SQL Server DBA Tips...
leader.

View all my tips

Comments For This Article

Add Comment

Follow Learning Resources Search Community More Info


Get Free SQL Tips DBAs Tutorials Tip Categories First Timer? Join
Twitter Developers Webcasts Search By TipID Pictures About
LinkedIn BI Professionals Whitepapers Authors Contribute Copyright
Facebook Careers Tools Event Calendar Privacy
Pinterest User Groups Disclaimer
RSS Author of the Year Feedback
Advertise

Copyright (c) 2006-2021 Edgewood Solutions, LLC All rights reserved


Some names and products listed are the registered trademarks of their respective owners.

You might also like