Skip to content

Commit 6f0e204

Browse files
committed
sp_BlitzIndex: Added warning for persisted sample rates.
1 parent 4263602 commit 6f0e204

2 files changed

Lines changed: 36 additions & 10 deletions

File tree

Documentation/sp_BlitzIndex_Checks_by_Priority.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Before adding a new check, make sure to add a Github issue for it first, and hav
66

77
If you want to change anything about a check - the priority, finding, URL, or ID - open a Github issue first. The relevant scripts have to be updated too.
88

9-
CURRENT HIGH CHECKID: 124
10-
If you want to add a new check, start at 125.
9+
CURRENT HIGH CHECKID: 125
10+
If you want to add a new check, start at 126.
1111

1212
| Priority | FindingsGroup | Finding | URL | CheckID |
1313
| -------- | ----------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------- | ------- |
@@ -25,6 +25,7 @@ If you want to add a new check, start at 125.
2525
| 80 | Abnormal Design Pattern | Filter Columns Not In Index Definition | https://www.brentozar.com/go/IndexFeatures | 34 |
2626
| 80 | Abnormal Design Pattern | History Table With NonClustered Index | https://sqlserverfast.com/blog/hugo/2023/09/an-update-on-merge/ | 124 |
2727
| 90 | Statistics Warnings | Low Sampling Rates | https://www.brentozar.com/go/stats | 91 |
28+
| 90 | Statistics Warnings | Persisted Sampling Rates | https://www.youtube.com/watch?v=V5illj_KOJg&t=758s | 125 |
2829
| 90 | Statistics Warnings | Statistics Not Updated Recently | https://www.brentozar.com/go/stats | 90 |
2930
| 90 | Statistics Warnings | Statistics with NO RECOMPUTE | https://www.brentozar.com/go/stats | 92 |
3031
| 100 | Over-Indexing | NC index with High Writes:Reads | https://www.brentozar.com/go/IndexHoarder | 48 |

sp_BlitzIndex.sql

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,8 @@ IF OBJECT_ID('tempdb..#dm_db_index_operational_stats') IS NOT NULL
738738
table_modify_date DATETIME NULL,
739739
no_recompute BIT NULL,
740740
has_filter BIT NULL,
741-
filter_definition NVARCHAR(MAX) NULL
741+
filter_definition NVARCHAR(MAX) NULL,
742+
has_persisted_sample BIT NULL
742743
);
743744

744745
CREATE TABLE #ComputedColumns
@@ -2279,7 +2280,7 @@ OPTION (RECOMPILE);';
22792280
INSERT #Statistics ( database_id, database_name, table_name, schema_name, index_name, column_names, statistics_name, last_statistics_update,
22802281
days_since_last_stats_update, rows, rows_sampled, percent_sampled, histogram_steps, modification_counter,
22812282
percent_modifications, modifications_before_auto_update, index_type_desc, table_create_date, table_modify_date,
2282-
no_recompute, has_filter, filter_definition)
2283+
no_recompute, has_filter, filter_definition, has_persisted_sample)
22832284
SELECT DB_ID(N' + QUOTENAME(@DatabaseName,'''') + N') AS [database_id],
22842285
@i_DatabaseName AS database_name,
22852286
obj.name AS table_name,
@@ -2306,7 +2307,12 @@ OPTION (RECOMPILE);';
23062307
CONVERT(DATETIME, obj.modify_date) AS table_modify_date,
23072308
s.no_recompute,
23082309
s.has_filter,
2309-
s.filter_definition
2310+
s.filter_definition,
2311+
'
2312+
+ CASE WHEN (PARSENAME(@SQLServerProductVersion, 4) >= 15)
2313+
THEN N's.has_persisted_sample'
2314+
ELSE N'NULL AS has_persisted_sample' END
2315+
+ N'
23102316
FROM ' + QUOTENAME(@DatabaseName) + N'.sys.stats AS s
23112317
JOIN ' + QUOTENAME(@DatabaseName) + N'.sys.objects obj
23122318
ON s.object_id = obj.object_id
@@ -2354,7 +2360,7 @@ OPTION (RECOMPILE);';
23542360
INSERT #Statistics(database_id, database_name, table_name, schema_name, index_name, column_names, statistics_name,
23552361
last_statistics_update, days_since_last_stats_update, rows, modification_counter,
23562362
percent_modifications, modifications_before_auto_update, index_type_desc, table_create_date, table_modify_date,
2357-
no_recompute, has_filter, filter_definition)
2363+
no_recompute, has_filter, filter_definition, has_persisted_sample)
23582364
SELECT DB_ID(N' + QUOTENAME(@DatabaseName,'''') + N') AS [database_id],
23592365
@i_DatabaseName AS database_name,
23602366
obj.name AS table_name,
@@ -2379,9 +2385,11 @@ OPTION (RECOMPILE);';
23792385
'
23802386
+ CASE WHEN @SQLServerProductVersion NOT LIKE '9%'
23812387
THEN N's.has_filter,
2382-
s.filter_definition'
2388+
s.filter_definition,'
23832389
ELSE N'NULL AS has_filter,
2384-
NULL AS filter_definition' END
2390+
NULL AS filter_definition,' END
2391+
/* If we are on this branch, then we cannot have the has_persisted_sample column (it is a 2019+ column). */
2392+
+ N'NULL AS has_persisted_sample'
23852393
+ N'
23862394
FROM ' + QUOTENAME(@DatabaseName) + N'.sys.stats AS s
23872395
INNER HASH JOIN ' + QUOTENAME(@DatabaseName) + N'.sys.sysindexes si
@@ -4454,7 +4462,7 @@ BEGIN
44544462
END;
44554463

44564464
----------------------------------------
4457-
--Statistics Info: Check_id 90-99
4465+
--Statistics Info: Check_id 90-99, as well as 125
44584466
----------------------------------------
44594467

44604468
RAISERROR(N'check_id 90: Outdated statistics', 0,1) WITH NOWAIT;
@@ -4503,6 +4511,24 @@ BEGIN
45034511
OR (s.rows > 1000000 AND s.percent_sampled < 1)
45044512
OPTION ( RECOMPILE );
45054513

4514+
RAISERROR(N'check_id 125: Statistics with a persisted sample rate', 0,1) WITH NOWAIT;
4515+
INSERT #BlitzIndexResults ( check_id, Priority, findings_group, finding, [database_name], URL, details, index_definition,
4516+
secret_columns, index_usage_summary, index_size_summary )
4517+
SELECT 125 AS check_id,
4518+
90 AS Priority,
4519+
'Statistics Warnings' AS findings_group,
4520+
'Persisted Sampling Rates',
4521+
s.database_name,
4522+
'https://www.youtube.com/watch?v=V5illj_KOJg&t=758s' AS URL,
4523+
'The statistics sample rate/amount has been persisted here. ' + CONVERT(NVARCHAR(100), s.percent_sampled) + '% of the rows were sampled during the last statistics update. This may indicate that somebody is doing statistics rocket surgery. Perhaps you would be better off updating statistics more frequently?' AS details,
4524+
QUOTENAME(database_name) + '.' + QUOTENAME(s.schema_name) + '.' + QUOTENAME(s.table_name) + '.' + QUOTENAME(s.index_name) + '.' + QUOTENAME(s.statistics_name) + '.' + QUOTENAME(s.column_names) AS index_definition,
4525+
'N/A' AS secret_columns,
4526+
'N/A' AS index_usage_summary,
4527+
'N/A' AS index_size_summary
4528+
FROM #Statistics AS s
4529+
WHERE s.has_persisted_sample = 1
4530+
OPTION ( RECOMPILE );
4531+
45064532
RAISERROR(N'check_id 92: Statistics with NO RECOMPUTE', 0,1) WITH NOWAIT;
45074533
INSERT #BlitzIndexResults ( check_id, Priority, findings_group, finding, [database_name], URL, details, index_definition,
45084534
secret_columns, index_usage_summary, index_size_summary )
@@ -4521,7 +4547,6 @@ BEGIN
45214547
WHERE s.no_recompute = 1
45224548
OPTION ( RECOMPILE );
45234549

4524-
45254550
RAISERROR(N'check_id 94: Check Constraints That Reference Functions', 0,1) WITH NOWAIT;
45264551
INSERT #BlitzIndexResults ( check_id, Priority, findings_group, finding, [database_name], URL, details, index_definition,
45274552
secret_columns, index_usage_summary, index_size_summary )

0 commit comments

Comments
 (0)