Statistics

Following up on my last post about the Cardinality Estimator, let’s talk about column statistics and how they work and play a part in execution plans. The cardinality estimator relies heavily on statistics to get the answer to selectivity (the ratio of distinct values to the total number of values) questions and calculate a cost estimate. This hopefully gives us the best possible execution plans for queries. In this post, I will show you where to find information about what your statistics contain and information regarding each of those fields. Then we will look at the impact of over and underestimations caused by stale or missing statistics (or even data skew). Finally, you will learn the best approaches to statistics maintenance.

Breaking Down the Stats

Statistics are made up of three parts. Each part tells the optimizer important information regarding the making of the table’s data distribution.

Let’s look at a Header, Density and Histogram example.

You can read what the statistic is broken down into using DBCC SHOW_STATISTICS. All field definitions are taken from MSDN.

This is from AdventureWorks2016CTP3 sample database if you want to follow along. Using the Sales. SalesOrderDetail table let’s look the stats and see what we can find out what it shows us.

Example Statistic

Statistics

STAT_HEADER

DBCC SHOW_STATISTICS ('[Sales].[SalesOrderDetail]',[_WA_Sys_00000001_57DD0BE4]) WITH STAT_HEADER;

ENGLISH

This table has keys averaging 4 bytes and 3.366 distinct key values out of 121,317 total rows. Now looking at the row you'll note you don't see 3.366 anywhere. That's because I calculated it as 1/.2727844 which was the Density value in the row. As you can see this stat has not been updated since 2015.

Statistics

DENSITY_VECTOR

DBCC SHOW_STATISTICS ('[Sales].[SalesOrderDetail]',[_WA_Sys_00000001_57DD0BE4]) WITH DENSITY_VECTOR;

ENGLISH

The SalesOrderID column can have 29,753 distinct combinations. How did I get that number? You take 1 divided by the all All Density number in this case .0000336114. Higher the density lowers the selectivity.

Statistics

HISTOGRAM

DBCC SHOW_STATISTICS ('[Sales].[SalesOrderDetail]',[_WA_Sys_00000001_57DD0BE4]) WITH HISTOGRAM;

ENGLISH

The histogram is showing us the frequency of occurrence for each distinct value in a data set. Let’s look at the first two rows. Our starting value is 43639 if we step from that value to the next HI_KEY 43692 we see that the distribution of that data says there are 32 distinct combinations between row 1 and row 2 and 311 rows in between them. EQ Rows tells us that at the 2 step (row 2) there are 28 values that equal the row value (43692). I find the Histogram very confusing so if you not following it’s ok. 😊 Read again and think of step ladder. The space in between each wrung is data.

Statistics

Now, let's take a look at how you can keep these numbers as accurate as possible.

Statistics Maintenance

It is very import to keep statistics up to date to ensure the Actual rows and Estimated rows are as aligned as closely as possible. For each insert, update, and delete change the data the distribution changes and can skew your estimations. These skews can lead to less than optimal query plans and performance degradation. Setting up a weekly update statistics job can help keep them up to date. (Note: some systems may require far more frequent updates--I’ve had to update stats every 10 minutes on a particularly troublesome table). Also, make sure you have AUTO_UPDATE_STATISTICS set. However, note this option will only update statistics created for indexes or single-columns in query predicates. Luckily, it also updates those you have manually created with the CREATE STATISTICS statement.

AUTO_UPDATE_STATISTICS triggers a statistics update based on a threshold of 20% row change. Now as you can imagine for large tables achieving the percent change needed to trigger an update can take a long time and often results in stale statistics on larger tables. To solve this issue, you can use Trace Flag 2371 to the lower the threshold that will trigger an update of the statistics on a sliding scale. Recognizing that this can be a real issue, this is now set as a default in 2016 or later.

Estimation Skews

In looking for skews pay attention to the difference between ACTUAL and ESTIMATED

Statistics

Underestimations can lead to …

Statistics

Adversely, overestimations will lead to….

Statistics

For the query optimizer to generate the best plan possible statistics need to be cared for and carefully maintained. You also need an understanding of what they are and how they are used. If you are using SQL Server 2017 in conjunction with column store indexes, there are some improvements for this, for the rest of you, you should ensure your stats are up to date.