Skip to content

Commit e6bf3e9

Browse files
Add check 17: top deadlock queries by involvement (BrentOzarULTD#3899)
Ranks all queries (procs and ad-hoc) by how frequently they appear in deadlocks, with victim vs. survivor breakdown. Groups by sql_handle + statement offsets from the execution stack, deduplicates to one frame per participant to avoid double-counting from nested calls. Shows each query's percentage of total deadlocks with a 10% significance cutoff. Closes BrentOzarULTD#3899 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b8f084e commit e6bf3e9

1 file changed

Lines changed: 169 additions & 0 deletions

File tree

sp_BlitzLock.sql

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3554,6 +3554,175 @@ To use sp_BlitzLock in Azure SQL DB, you have two options:
35543554

35553555
RAISERROR('Finished at %s', 0, 1, @d) WITH NOWAIT;
35563556

3557+
/*Check 17 is top deadlock queries by involvement*/
3558+
SET @d = CONVERT(varchar(40), GETDATE(), 109);
3559+
RAISERROR('Check 17 top deadlock queries %s', 0, 1, @d) WITH NOWAIT;
3560+
3561+
WITH
3562+
top_frame AS
3563+
(
3564+
SELECT
3565+
ds.id,
3566+
ds.event_date,
3567+
ds.proc_name,
3568+
ds.sql_handle,
3569+
ds.stmtstart,
3570+
ds.stmtend,
3571+
rn =
3572+
ROW_NUMBER() OVER
3573+
(
3574+
PARTITION BY
3575+
ds.id,
3576+
ds.event_date
3577+
ORDER BY
3578+
ds.stmtstart
3579+
)
3580+
FROM #deadlock_stack AS ds
3581+
WHERE ds.sql_handle <> N'0x'
3582+
AND ds.sql_handle <> N''
3583+
AND ds.sql_handle IS NOT NULL
3584+
),
3585+
deadlock_queries AS
3586+
(
3587+
SELECT
3588+
dp.database_name,
3589+
tf.sql_handle,
3590+
tf.stmtstart,
3591+
tf.stmtend,
3592+
tf.proc_name,
3593+
dp.event_date,
3594+
dp.is_victim,
3595+
inputbuf =
3596+
dp.process_xml.value
3597+
(
3598+
'(//process/inputbuf/text())[1]',
3599+
'nvarchar(256)'
3600+
)
3601+
FROM top_frame AS tf
3602+
JOIN #deadlock_process AS dp
3603+
ON dp.id = tf.id
3604+
AND dp.event_date = tf.event_date
3605+
WHERE tf.rn = 1
3606+
AND (dp.database_name = @DatabaseName OR @DatabaseName IS NULL)
3607+
AND (dp.event_date >= @StartDate OR @StartDate IS NULL)
3608+
AND (dp.event_date < @EndDate OR @EndDate IS NULL)
3609+
AND (dp.client_app = @AppName OR @AppName IS NULL)
3610+
AND (dp.host_name = @HostName OR @HostName IS NULL)
3611+
AND (dp.login_name = @LoginName OR @LoginName IS NULL)
3612+
)
3613+
INSERT
3614+
#deadlock_findings WITH(TABLOCKX)
3615+
(
3616+
check_id,
3617+
database_name,
3618+
object_name,
3619+
finding_group,
3620+
finding,
3621+
sort_order
3622+
)
3623+
SELECT
3624+
check_id = 17,
3625+
dq.database_name,
3626+
object_name =
3627+
LEFT
3628+
(
3629+
REPLACE
3630+
(
3631+
REPLACE
3632+
(
3633+
CASE
3634+
WHEN dq.proc_name <> N'adhoc'
3635+
THEN dq.proc_name
3636+
ELSE
3637+
ISNULL
3638+
(
3639+
MAX(dq.inputbuf),
3640+
N'[Unknown]'
3641+
)
3642+
END,
3643+
NCHAR(13),
3644+
N' '
3645+
),
3646+
NCHAR(10),
3647+
N' '
3648+
),
3649+
200
3650+
),
3651+
finding_group = N'Top Deadlock Query',
3652+
finding =
3653+
N'This query was involved in ' +
3654+
CONVERT
3655+
(
3656+
nvarchar(20),
3657+
COUNT_BIG(DISTINCT dq.event_date)
3658+
) +
3659+
N' deadlocks (victim ' +
3660+
CONVERT
3661+
(
3662+
nvarchar(20),
3663+
SUM
3664+
(
3665+
CONVERT(int, dq.is_victim)
3666+
)
3667+
) +
3668+
N' times, survived ' +
3669+
CONVERT
3670+
(
3671+
nvarchar(20),
3672+
COUNT_BIG(DISTINCT dq.event_date) -
3673+
SUM
3674+
(
3675+
CONVERT(int, dq.is_victim)
3676+
)
3677+
) +
3678+
N' times), ' +
3679+
ISNULL
3680+
(
3681+
CONVERT
3682+
(
3683+
nvarchar(10),
3684+
CONVERT
3685+
(
3686+
decimal(5, 1),
3687+
100.0 *
3688+
COUNT_BIG(DISTINCT dq.event_date) /
3689+
NULLIF
3690+
(
3691+
SUM
3692+
(
3693+
COUNT_BIG(DISTINCT dq.event_date)
3694+
) OVER (),
3695+
0
3696+
)
3697+
)
3698+
),
3699+
N'0.0'
3700+
) +
3701+
N'% of total.',
3702+
sort_order =
3703+
ROW_NUMBER() OVER
3704+
(
3705+
ORDER BY
3706+
COUNT_BIG(DISTINCT dq.event_date) DESC
3707+
)
3708+
FROM deadlock_queries AS dq
3709+
GROUP BY
3710+
dq.database_name,
3711+
dq.sql_handle,
3712+
dq.stmtstart,
3713+
dq.stmtend,
3714+
dq.proc_name
3715+
HAVING
3716+
COUNT_BIG(DISTINCT dq.event_date) * 10 >=
3717+
(
3718+
SELECT
3719+
COUNT_BIG(DISTINCT dq2.event_date)
3720+
FROM deadlock_queries AS dq2
3721+
)
3722+
OPTION(RECOMPILE);
3723+
3724+
RAISERROR('Finished at %s', 0, 1, @d) WITH NOWAIT;
3725+
35573726
/*Thank you goodnight*/
35583727
INSERT
35593728
#deadlock_findings WITH(TABLOCKX)

0 commit comments

Comments
 (0)