Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
6a520fb
Protect unique indexes from sp_IndexCleanup Rule 1 and fix Rule 7 match
erikdarlingdata Apr 19, 2026
910cbb4
Protect narrower unique indexes from sp_IndexCleanup Rule 3 supersession
erikdarlingdata Apr 19, 2026
c9efb7d
Guard sp_IndexCleanup Rule 7.5 against foreign-key dependencies
erikdarlingdata Apr 19, 2026
e9eaee8
Protect primary keys from sp_IndexCleanup Rule 2 and Rule 5 DISABLE
erikdarlingdata Apr 19, 2026
096db4e
Reject READ_ONLY and ERROR Query Store states in sp_QueryStoreCleanup
erikdarlingdata Apr 19, 2026
427fa9f
Use MIN/MAX/AVG for sp_QuickieStore wait-time column aggregations
erikdarlingdata Apr 19, 2026
344fff5
Fix sp_PerfCheck deadlock check for sub-day uptime
erikdarlingdata Apr 19, 2026
4202a17
Fix sp_HumanEventsBlockViewer last_transaction_started attribute mism…
erikdarlingdata Apr 19, 2026
0a453c3
Coerce sp_HumanEvents @seconds_sample = 0/NULL to 1 second
erikdarlingdata Apr 19, 2026
0c5f43d
Preserve decimal precision in sp_PressureDetector size/memory GB math
erikdarlingdata Apr 19, 2026
e768943
Escape double quotes in sp_LogHunter @custom_message
erikdarlingdata Apr 19, 2026
300ec24
Cap sp_IndexCleanup subset-chain resolution at 100 iterations
erikdarlingdata Apr 19, 2026
c01543b
Guard sp_HumanEventsBlockViewer recursive blocking-tree against cycles
erikdarlingdata Apr 19, 2026
f2d3b2a
Gate sp_PerfCheck LPIM recommendation off Azure MI and AWS RDS
erikdarlingdata Apr 19, 2026
186c214
Merge fix/index-cleanup-unique-index-protection into dev
erikdarlingdata Apr 19, 2026
2493a35
Merge fix/index-cleanup-chain-cycle-cap into dev
erikdarlingdata Apr 19, 2026
09d1018
Merge fix/query-store-cleanup-readonly into dev
erikdarlingdata Apr 19, 2026
6b0a375
Merge fix/quickiestore-wait-aggregation into dev
erikdarlingdata Apr 19, 2026
e7b555f
Merge fix/perfcheck-deadlock-uptime-guard into dev
erikdarlingdata Apr 19, 2026
92f4e3b
Merge fix/perfcheck-lpim-aws-rds-gate into dev
erikdarlingdata Apr 19, 2026
ff9e575
Merge fix/humanevents-seconds-sample-validation into dev
erikdarlingdata Apr 19, 2026
d7d74b0
Merge fix/blockviewer-transaction-attribute-mismatch into dev
erikdarlingdata Apr 19, 2026
24ca7f2
Merge fix/blockviewer-recursive-cte-cycle-guard into dev
erikdarlingdata Apr 19, 2026
d92cd42
Merge fix/pressuredetector-integer-division into dev
erikdarlingdata Apr 19, 2026
fc16d14
Merge fix/loghunter-custom-message-escape into dev
erikdarlingdata Apr 19, 2026
ff3bc32
Remove sp_QuickieStore wait-stats per-interval TOP (5) pre-filter
erikdarlingdata Apr 19, 2026
fe8189f
Merge fix/quickiestore-wait-stats-top5 into dev
erikdarlingdata Apr 19, 2026
4ffacfa
Anchor sp_HumanEvents cleanup LIKE to its own session names
erikdarlingdata Apr 19, 2026
e185df8
Merge fix/humanevents-cleanup-like-anchor into dev
erikdarlingdata Apr 19, 2026
b7add51
Weight sp_QuickieStore regression comparator by count_executions
erikdarlingdata Apr 19, 2026
1057e2b
Merge fix/quickiestore-regression-weighted-avg into dev
erikdarlingdata Apr 19, 2026
48315e8
Add @pause_milliseconds batch pacing to sp_QueryStoreCleanup
erikdarlingdata Apr 19, 2026
7a9919f
Merge fix/query-store-cleanup-batch-pacing into dev
erikdarlingdata Apr 19, 2026
c460316
Honor @pending_task_threshold in sp_HealthParser scheduler shreds
erikdarlingdata Apr 19, 2026
731c746
Merge fix/healthparser-pending-task-threshold into dev
erikdarlingdata Apr 19, 2026
dc6e56d
Use AND between @dbid and @database_name filter groups in sp_HealthPa…
erikdarlingdata Apr 19, 2026
2f23916
Merge fix/healthparser-deadlock-filter-and into dev
erikdarlingdata Apr 19, 2026
ba3bbc2
Batch sp_HealthParser log-retention DELETEs in 10k-row chunks
erikdarlingdata Apr 19, 2026
8d54a5d
Merge fix/healthparser-cleanup-delete-batch into dev
erikdarlingdata Apr 19, 2026
e4b081f
Weight sp_HealthParser #tc wait average by waits count
erikdarlingdata Apr 19, 2026
2f3544b
Merge fix/healthparser-wait-avg-weighting into dev
erikdarlingdata Apr 19, 2026
db7a0b8
Align sp_HealthParser 2017+ XE time filter to half-open interval
erikdarlingdata Apr 19, 2026
85cc60e
Merge fix/healthparser-interval-boundary-consistency into dev
erikdarlingdata Apr 19, 2026
f594e12
Fix sp_LogHunter custom_message_only validation and canary date floor
erikdarlingdata Apr 19, 2026
8d78e01
Merge fix/loghunter-custom-only-and-canary-dates into dev
erikdarlingdata Apr 19, 2026
35399ce
Revert "Merge fix/healthparser-cleanup-delete-batch into dev"
erikdarlingdata Apr 19, 2026
52b7c0c
Revert "Merge fix/query-store-cleanup-batch-pacing into dev"
erikdarlingdata Apr 19, 2026
5e62cfb
Revert "Merge fix/blockviewer-transaction-attribute-mismatch into dev"
erikdarlingdata Apr 19, 2026
e46bbc1
Revert "Merge fix/index-cleanup-chain-cycle-cap into dev"
erikdarlingdata Apr 19, 2026
3e0e6d1
Revert "Protect primary keys from sp_IndexCleanup Rule 2 and Rule 5 D…
erikdarlingdata Apr 19, 2026
3763df5
Correlate sample_sql_handle / sample_plan_handle to the same row in s…
erikdarlingdata Apr 20, 2026
2f53541
Merge fix/quickiecache-handle-aggregation into dev
erikdarlingdata Apr 20, 2026
0b68dd5
Document @timestamp_column UTC convention in sp_HumanEventsBlockViewer
erikdarlingdata Apr 20, 2026
a64ede3
Merge fix/blockviewer-timestamp-column-docs into dev
erikdarlingdata Apr 20, 2026
52fc3bf
Flag the @regression_where_clause REPLACE fragility in sp_QuickieStore
erikdarlingdata Apr 20, 2026
6f105be
Merge fix/quickiestore-regression-replace-comment into dev
erikdarlingdata Apr 20, 2026
82e08d9
Remove SUBSTRING(..., 0, 8000) wrapper from sp_HumanEvents wait-type …
erikdarlingdata Apr 20, 2026
c28b500
Merge fix/humanevents-wait-type-filter-truncation into dev
erikdarlingdata Apr 20, 2026
602d09c
Fix SUBSTRING length-vs-endpos in debug @sql chunk-print across 3 sprocs
erikdarlingdata Apr 20, 2026
0b803cf
Merge fix/debug-print-chunk-tiling into dev
erikdarlingdata Apr 20, 2026
f1142ce
Compute sp_PressureDetector sample-mode percent_signal_waits from raw…
erikdarlingdata Apr 20, 2026
6912c28
Merge fix/pressuredetector-sample-signal-waits-delta into dev
erikdarlingdata Apr 20, 2026
d010b26
Use CONVERT instead of RTRIM for int->nvarchar in sp_HumanEventsBlock…
erikdarlingdata Apr 20, 2026
95b2452
Merge fix/blockviewer-rtrim-int-explicit-convert into dev
erikdarlingdata Apr 20, 2026
b134642
Normalize database_name / currentdbname columns to sysname in sp_Huma…
erikdarlingdata Apr 20, 2026
6b0e09c
Merge fix/blockviewer-currentdbname-sysname into dev
erikdarlingdata Apr 20, 2026
d49d858
Honor @gimme_danger in sp_HumanEvents table-logging wait insert
erikdarlingdata Apr 20, 2026
d5e07be
Merge fix/humanevents-table-log-gimme-danger into dev
erikdarlingdata Apr 20, 2026
48a8902
Fix remaining SUBSTRING length-vs-endpos chunk-print bugs across sprocs
erikdarlingdata Apr 20, 2026
82cb9b4
Merge fix/humanevents-chunk-print-tiling into dev
erikdarlingdata Apr 20, 2026
7bd5bfc
Fix inverted recent-modification guard in sp_HumanEvents view-recreat…
erikdarlingdata Apr 20, 2026
784c6fe
Merge fix/humanevents-view-recreation-guard-inverted into dev
erikdarlingdata Apr 20, 2026
3622aea
Document intentional event_file preference in sp_HumanEventsBlockView…
erikdarlingdata Apr 20, 2026
128ecea
Merge fix/blockviewer-target-detect-comment into dev
erikdarlingdata Apr 20, 2026
9165e76
Case-insensitively compare @target_type = 'ring_buffer' in sp_HumanEv…
erikdarlingdata Apr 20, 2026
66662a3
Merge fix/blockviewer-target-type-case-insensitive into dev
erikdarlingdata Apr 20, 2026
1ca8808
Add configuration_id 17 (ISOLATE_SECURITY_POLICY_CARDINALITY) to sp_P…
erikdarlingdata Apr 20, 2026
8c64642
Merge fix/perfcheck-dsc-isolate-security-policy-17 into dev
erikdarlingdata Apr 20, 2026
58817cd
Treat sp_QuickieStore as 2022-class when >=4 of 5 QS views exist
erikdarlingdata Apr 20, 2026
7ce0c15
Merge fix/quickiestore-2022-views-threshold into dev
erikdarlingdata Apr 20, 2026
5f7d7a9
Remove per-row @minimum_execution_count pre-filter in sp_QuickieCache
erikdarlingdata Apr 20, 2026
18d9621
Merge fix/quickiecache-min-exec-prefilter into dev
erikdarlingdata Apr 20, 2026
4bbd3f2
Bump sp_PerfCheck check_id 1002 (max memory near physical RAM) to pri…
erikdarlingdata Apr 20, 2026
e365d4c
Merge fix/perfcheck-max-memory-near-ram-priority into dev
erikdarlingdata Apr 20, 2026
c77222f
Gate sp_PerfCheck dm_os_memory_health_history read on VIEW SERVER STATE
erikdarlingdata Apr 20, 2026
5aeba60
Merge fix/perfcheck-memory-health-history-vss-gate into dev
erikdarlingdata Apr 20, 2026
c79ad73
Tighten sp_PerfCheck stolen-memory counter filter
erikdarlingdata Apr 20, 2026
8fec487
Merge fix/perfcheck-stolen-server-filter-tighten into dev
erikdarlingdata Apr 20, 2026
1b9ba45
Split sp_PerfCheck pagelatch/uptime scalar assignment into two SELECTs
erikdarlingdata Apr 20, 2026
67ffe7f
Merge fix/perfcheck-uptime-pagelatch-scalars into dev
erikdarlingdata Apr 20, 2026
3d5bf7b
Honor @start_date / @end_date in sp_QuickieCache single-use-plans mode
erikdarlingdata Apr 20, 2026
d51f109
Merge fix/quickiecache-single-use-date-filters into dev
erikdarlingdata Apr 20, 2026
d85c660
Normalize @database_id filter on sql_variant pa.value in sp_QuickieCache
erikdarlingdata Apr 20, 2026
625a845
Merge fix/quickiecache-sql-variant-convert-consistency into dev
erikdarlingdata Apr 20, 2026
ccb22a0
Bump all procs to X.5 for 4/20 release
erikdarlingdata Apr 20, 2026
1781619
Merge release/4.20 into dev
erikdarlingdata Apr 20, 2026
a376719
Merge main automation commits into dev
erikdarlingdata Apr 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 46 additions & 9 deletions sp_HealthParser/sp_HealthParser.sql
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT
@version = '3.4',
@version_date = '20260401';
@version = '3.5',
@version_date = '20260420';

IF @help = 1
BEGIN
Expand Down Expand Up @@ -435,15 +435,24 @@ AND ca.utc_timestamp < @end_date';
END;
ELSE
BEGIN
/* 2017+ handling */
/*
2017+ handling. Use the same half-open (>= @start_date AND
< @end_date) shape as the pre-2017 branch so an event captured
at exactly @end_date is not included on 2017+ while excluded
on pre-2017 — previously BETWEEN meant a closed interval on
2017+ and a row at the boundary could appear or not depending
on which branch ran.
*/
SET @cross_apply = N'CROSS APPLY xml.{object_name}.nodes(''/event'') AS e(x)';

IF @timestamp_utc_mode = 1
SET @time_filter = N'
AND CONVERT(datetimeoffset(7), fx.timestamp_utc) BETWEEN @start_date AND @end_date';
AND CONVERT(datetimeoffset(7), fx.timestamp_utc) >= @start_date
AND CONVERT(datetimeoffset(7), fx.timestamp_utc) < @end_date';
ELSE
SET @time_filter = N'
AND fx.timestamp_utc BETWEEN @start_date AND @end_date';
AND fx.timestamp_utc >= @start_date
AND fx.timestamp_utc < @end_date';
END;

SET @sql_template =
Expand Down Expand Up @@ -2218,7 +2227,21 @@ AND ca.utc_timestamp < @end_date';
),
tc.wait_type,
waits = SUM(CONVERT(bigint, tc.waits)),
average_wait_time_ms = CONVERT(bigint, AVG(tc.average_wait_time_ms)),
/*
Weighted average rather than AVG(avg): tc.average_wait_time_ms
is already a per-event average, so AVG() over the bucket was
an unweighted mean of means — events with one wait got the
same pull on the output as events with thousands. Weight by
waits to get the true bucket-scoped average. NULLIF keeps us
safe if every contributing row had waits = 0.
*/
average_wait_time_ms =
CONVERT
(
bigint,
SUM(CONVERT(decimal(38, 2), tc.average_wait_time_ms) * CONVERT(decimal(38, 2), tc.waits))
/ NULLIF(SUM(CONVERT(decimal(38, 2), tc.waits)), 0)
),
max_wait_time_ms = CONVERT(bigint, MAX(tc.max_wait_time_ms))
INTO #tc
FROM #topwaits_count AS tc
Expand Down Expand Up @@ -2951,7 +2974,11 @@ AND ca.utc_timestamp < @end_date';
CROSS APPLY wi.sp_server_diagnostics_component_result.nodes('/event') AS w(x)
WHERE w.x.exist('(data[@name="component"]/text[.= "QUERY_PROCESSING"])') = 1
AND (w.x.exist('(data[@name="state"]/text[.= "WARNING"])') = @warnings_only OR @warnings_only = 0)
AND (w.x.exist('(/event/data[@name="data"]/value/queryProcessing/@pendingTasks[.>= sql:variable("@pending_task_threshold")])') = 1 OR @warnings_only = 0)
/* Threshold is honored whether or not @warnings_only is set — the
parameter documents "minimum pending tasks to display" and the
previous `OR @warnings_only = 0` short-circuit silently ignored
the user-supplied value whenever warnings-only was off. */
AND w.x.exist('(/event/data[@name="data"]/value/queryProcessing/@pendingTasks[.>= sql:variable("@pending_task_threshold")])') = 1
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropping OR @warnings_only = 0 is a behavior change for callers that ran with the default and relied on the threshold being ignored outside warnings-only mode. The parameter help text in the @help block doesn't mention the new floor — worth a one-line update so callers don't get surprised by fewer rows after upgrading.


Generated by Claude Code

OPTION(RECOMPILE, MAXDOP 1);

IF @debug = 1
Expand Down Expand Up @@ -3176,7 +3203,10 @@ AND ca.utc_timestamp < @end_date';
INTO #pending_task_details
FROM #sp_server_diagnostics_component_result AS wi
CROSS APPLY wi.sp_server_diagnostics_component_result.nodes('/event') AS w(x)
CROSS APPLY w.x.nodes('/event/data[@name="data"]/value/queryProcessing[@pendingTasks > 1]/pendingTasks/entryPoint') AS ep(e)
/* Hardcoded threshold > 1 ignored the @pending_task_threshold
parameter. Replaced with sql:variable() binding so the user's
value actually takes effect here too. */
CROSS APPLY w.x.nodes('/event/data[@name="data"]/value/queryProcessing[@pendingTasks >= sql:variable("@pending_task_threshold")]/pendingTasks/entryPoint') AS ep(e)
WHERE w.x.exist('(data[@name="component"]/text[.= "QUERY_PROCESSING"])') = 1
AND (w.x.exist('(data[@name="state"]/text[.= "WARNING"])') = @warnings_only OR @warnings_only = 0)
OPTION(RECOMPILE, MAXDOP 1);
Expand Down Expand Up @@ -5721,9 +5751,16 @@ AND ca.utc_timestamp < @end_date';
FROM #deadlocks AS d
CROSS APPLY d.xml_deadlock_report.nodes('//deadlock/process-list/process') AS e(x)
) AS x
/* Standard "filter if supplied, pass-through if NULL" predicate
pairs must be combined with AND between the groups — OR let
rows through whenever either parameter was NULL, which makes
the @database_name/@dbid filter loose whenever only one side
was supplied. Currently masked because the validation block
above aborts when the two disagree, but the shape was
wrong and would break if that validation ever relaxed. */
WHERE (x.database_id = @dbid
OR @dbid IS NULL)
OR (x.current_database_name = @database_name
AND (x.current_database_name = @database_name
OR @database_name IS NULL)
OPTION(RECOMPILE, MAXDOP 1);

Expand Down
Loading
Loading