|
| 1 | +/* |
| 2 | +Author: Taiob Ali |
| 3 | +Original link: http://sqlworldwide.com/tsql-to-find-status-of-sql-server-statistics/ |
| 4 | +
|
| 5 | +This code is a modified or extended version of a script from here: |
| 6 | +--http://www.sqlskills.com/blogs/erin/new-statistics-dmf-in-sql-server-2008r2-sp2/ |
| 7 | +
|
| 8 | +This script will give all metadata related to statistics for a single database. |
| 9 | +You can also uncomment a line and add an object name for a single table. |
| 10 | +
|
| 11 | +Final challenge was to get one row per statistics with all column names. Used the tips from |
| 12 | +https://www.mssqltips.com/sqlservertip/2914/rolling-up-multiple-rows-into-a-single-row-and-column-for-sql-server-data/ |
| 13 | +
|
| 14 | +Suneel Mundlapudi who is a Sr. SQL Server Database Consultant at Fresenius Medical Care helped me implementing STUFF function |
| 15 | +*/ |
| 16 | + |
| 17 | +/* Change on your database name */ |
| 18 | +USE master; |
| 19 | +GO |
| 20 | + |
| 21 | +IF Object_id('tempdb..#StatsInfo') IS NOT NULL |
| 22 | + DROP TABLE #StatsInfo; |
| 23 | +GO |
| 24 | + |
| 25 | +IF Object_id('tempdb..#ColumnList') IS NOT NULL |
| 26 | + DROP TABLE #ColumnList; |
| 27 | +GO |
| 28 | + |
| 29 | +DECLARE @object_id INT = NULL; |
| 30 | + |
| 31 | +--By default you get statistics status for whole database |
| 32 | +--Uncomment below line if you are only looking at one table |
| 33 | +--SET @object_id = OBJECT_ID(N'Sales.Invoices'); |
| 34 | +SELECT ss.[name] AS SchemaName, |
| 35 | + obj.[name] AS TableName, |
| 36 | + stat.[stats_id], |
| 37 | + stat.[name] AS StatisticsName, |
| 38 | + CASE |
| 39 | + WHEN stat.[auto_created] = 0 |
| 40 | + AND stat.[user_created] = 0 THEN 'Index Statistic' |
| 41 | + WHEN stat.[auto_created] = 0 |
| 42 | + AND stat.[user_created] = 1 THEN 'User Created' |
| 43 | + WHEN stat.[auto_created] = 1 |
| 44 | + AND stat.[user_created] = 0 THEN 'Auto Created' |
| 45 | + WHEN stat.[auto_created] = 1 |
| 46 | + AND stat.[user_created] = 1 THEN 'Updated stats available in Secondary' |
| 47 | + END AS StatisticType, |
| 48 | + CASE |
| 49 | + WHEN stat.[is_temporary] = 0 THEN 'Stats in DB' |
| 50 | + WHEN stat.[is_temporary] = 1 THEN 'Stats in Tempdb' |
| 51 | + END AS IsTemporary, |
| 52 | + CASE |
| 53 | + WHEN stat.[has_filter] = 1 THEN 'Filtered Index' |
| 54 | + WHEN stat.[has_filter] = 0 THEN 'No Filter' |
| 55 | + END AS IsFiltered, |
| 56 | + c.[name] AS ColumnName, |
| 57 | + stat.[filter_definition], |
| 58 | + sp.[last_updated], |
| 59 | + sp.[rows], |
| 60 | + sp.[rows_sampled], |
| 61 | + sp.[steps] AS HistorgramSteps, |
| 62 | + sp.[unfiltered_rows], |
| 63 | + sp.[modification_counter] AS RowsModified |
| 64 | +INTO #StatsInfo |
| 65 | +FROM sys.[objects] AS obj |
| 66 | + INNER JOIN sys.[schemas] ss |
| 67 | + ON obj.[schema_id] = ss.[schema_id] |
| 68 | + INNER JOIN sys.[stats] stat |
| 69 | + ON stat.[object_id] = obj.[object_id] |
| 70 | + JOIN sys.[stats_columns] sc |
| 71 | + ON sc.[object_id] = stat.[object_id] |
| 72 | + AND sc.[stats_id] = stat.[stats_id] |
| 73 | + JOIN sys.columns c |
| 74 | + ON c.[object_id] = sc.[object_id] |
| 75 | + AND c.[column_id] = sc.[column_id] |
| 76 | + CROSS apply sys.dm_db_stats_properties(stat.[object_id], stat.stats_id) AS |
| 77 | + sp |
| 78 | +WHERE ( obj.[is_ms_shipped] = 0 |
| 79 | + AND obj.[object_id] = @object_id ) |
| 80 | + OR ( obj.[is_ms_shipped] = 0 ) |
| 81 | +ORDER BY ss.[name], |
| 82 | + obj.[name], |
| 83 | + stat.[name]; |
| 84 | + |
| 85 | +SELECT t.SchemaName, |
| 86 | + t.TableName, |
| 87 | + t.[stats_id], |
| 88 | + STUFF((SELECT ',' + s.ColumnName |
| 89 | + FROM #StatsInfo s |
| 90 | + WHERE s.SchemaName = t.SchemaName |
| 91 | + AND s.TableName = t.TableName |
| 92 | + AND s.stats_id = t.stats_id |
| 93 | + FOR xml path('')), 1, 1, '') |
| 94 | + AS ColumnList |
| 95 | +INTO #ColumnList |
| 96 | +FROM #StatsInfo AS t |
| 97 | +GROUP BY t.SchemaName, |
| 98 | + t.TableName, |
| 99 | + t.stats_id; |
| 100 | + |
| 101 | +SELECT DISTINCT SI.SchemaName, |
| 102 | + SI.TableName, |
| 103 | + SI.stats_id, |
| 104 | + SI.StatisticsName, |
| 105 | + SI.StatisticType, |
| 106 | + SI.IsTemporary, |
| 107 | + CL.ColumnList AS ColumnName, |
| 108 | + SI.IsFiltered, |
| 109 | + SI.filter_definition, |
| 110 | + SI.last_updated, |
| 111 | + SI.[rows], |
| 112 | + SI.rows_sampled, |
| 113 | + SI.HistorgramSteps, |
| 114 | + SI.unfiltered_rows, |
| 115 | + SI.RowsModified |
| 116 | +FROM #StatsInfo SI |
| 117 | + INNER JOIN #ColumnList CL |
| 118 | + ON SI.SchemaName = CL.SchemaName |
| 119 | + AND SI.TableName = CL.TableName |
| 120 | + AND SI.stats_id = CL.stats_id |
| 121 | +ORDER BY SI.SchemaName, |
| 122 | + SI.TableName, |
| 123 | + SI.StatisticsName; |
| 124 | +GO |
0 commit comments