-
Notifications
You must be signed in to change notification settings - Fork 107
Reports via SQL Queries
This page provides queries that you can run directly against the SQL Nexus database to get useful information from your performance data. These queries mimic some of the GUI reports but mostly expand on them or provide more advanced analysis scenarios.
Below are the most common troubleshooting queries you can use in analyzing the SQL Nexus data:
select top 50 sum(b.Duration)/1000 Duration_ms, SUM(b. CPU) CPU_ms,
sum(b.Duration)/1000 - sum(b.CPU) WaitTime_ms, convert(decimal(8,2),
(((sum(b.duration)/1000.00) - sum(b.cpu))/(SUM(b.duration)/1000))*100) waitpercentage,
sum(b.Reads) Reads, COUNT(*) Executions, (sum(b.Duration)/1000)/COUNT(*) AvgDuration,
sum(b.CPU)/count(*) AvgCPU, substring(ub.NormText, 1, 100) NormText , b.HashID
from ReadTrace.tblBatches b
join ReadTrace.tblUniqueBatches ub
on b.HashID = ub.HashID
group by ub.NormText, b.HashID
order by Duration_ms descselect top 20000 b.Session, b.Duration/1000 Duration,
(b.CPU) CPU, (b.Reads) Reads, b.attnseq, b.starttime,
b.endtime, substring(u.OrigText, 1, 1000) OrigText, batchseq
from ReadTrace.tblBatches b
join ReadTrace.tblUniqueBatches u
on b.HashID = u.HashID
join ReadTrace.tblConnections c
on b.ConnSeq = c.ConnSeq and b.session = c.session
where b.HashID = 5155459154697299715
order by duration descSELECT Min(tb.StartTime) AS CollectionStartTime,
max(tb.EndTime) AS CollectionEndTime,
DATEDIFF(MINUTE, min(tb.starttime), max(tb.EndTime)) AS CollectionDuration_min
FROM ReadTrace.tblBatches tbIF OBJECT_ID ('DataSet_WaitStats_WaitStatsTop5Categories') IS NOT NULL AND OBJECT_ID ('tbl_OS_WAIT_STATS') IS NOT NULL
EXEC DataSet_WaitStats_WaitStatsTop5Categories select runtime,ecid,blocking_session_id, task_state, wait_type,
wait_duration_ms, wait_resource, tran_name, command, request_status
from tbl_REQUESTS r join ReadTrace.tblBatches b
on r.session_id = b.Session
and dateadd(hh, -2, r.runtime) between b.starttime and b.endtime --have to modify datediff to account for Xevents times vs. server times
where HashID = <hash_id> -- change this value as per your query returning
and task_state != 'running' and task_state != 'runnable' select runtime,ecid,blocking_session_id, task_state, wait_type,
wait_duration_ms, wait_resource, tran_name, command, request_status
from tbl_REQUESTS r
where session_id in (
select distinct top 20 t.session from ReadTrace.tblBatches t
where HashID = <hash_id> -- change this value as per your query returning
and r.runtime between t.starttime and t.endtime)
order by runtime ascselect count(*) occurrences, sum(r.wait_duration_ms) WaitDensity_ms, r.wait_type,
q.procname, q.stmt_text
from tbl_REQUESTS r
join tbl_NOTABLEACTIVEQUERIES q
on r.session_id = q.session_id
and r.runtime = q.runtime
where wait_type is not null
and wait_type not in ('SP_SERVER_DIAGNOSTICS_SLEEP', 'backupio', 'BROKER_RECEIVE_WAITFOR')
group by r.wait_type, q.procname, q.stmt_text
order by WaitDensity_ms descselect COUNT(*) occurrences, wait_resource, wait_type,
max(wait_duration_ms) maxWaitMs
from tbl_REQUESTS
where wait_type is not null
group by wait_resource, wait_type
order by occurrences descselect count(*) occurrences, wait_type
from tbl_REQUESTS r
where wait_type is not null
group by wait_type
order by occurrences Descselect runtime, head_blocker_session_id, head_blocker_proc_name,stmt_text as head_blocker_stmt,
blocked_task_count, tot_wait_duration_ms as blocked_total_wait_dur_ms,
avg_wait_duration_ms as blocked_avg_wait_dur_ms
from tbl_HEADBLOCKERSUMMARY
order by runtime Find all blocked spids throughout entire PSSDIAG/SQLLogScout collection and the queries they are running
select * from tbl_REQUESTS r join tbl_NOTABLEACTIVEQUERIES q
on r.session_id = q.session_id
and r.runtime = q.runtime
where blocking_session_id <> 0
order by r.rownumselect sum(cpu) CPU, sum(Duration/1000.0) Duration , count(*) Occurrences, ub.NormText
from ReadTrace.tblStatements b join ReadTrace.tblUniqueStatements ub
on b.HashID = ub.HashID
where b.BatchSeq = <BatchSeq ID> -- Please put here Batch Sequence ID
group by NormText
order by Duration Descselect * from ReadTrace.tblBatches b
join ReadTrace.tblConnections c
on b.ConnSeq = c.ConnSeq and b.session = c.session
where c.ApplicationName = 'sqlcmd'This script finds the top 100 long running queries for which the CPU time is less than 80% of Duration , meaning there was a wait. Then it finds what wait types are responsible for this wait and summarizes the total wait_time by wait type for that query. Feel free to change something else or change the 80% to a smaller percent as these are arbitrary choices. The latter would mean that if say 50% was chosen, then out of the total duration the query ran on the CPU only 50% of the time, and the rest it waited for something.
with BatchesData (Session, starttime, endtime, hashid, cpu,duration, CpuPercentOfDuration, NormText)
as
(
select Session, starttime, endtime, b.hashid, cpu,duration, (CPU/Duration)/1000 CpuPercentOfDuration, NormText
from ReadTrace.tblBatches b join ReadTrace.tblUniqueBatches ub
on b.HashID = ub.HashID
where duration !=0
)
select top 100 max(wait_duration_ms) MaxWaitDuration, r.wait_type, t.NormText--aggreate the duration per wait_type
from tbl_REQUESTS r
join BatchesData t
on r.runtime between t.starttime and t.endtime
and r.session_id = t.Session
where t.cpupercentofduration < 0.80 -- where CPU is less than 80% of duration
and task_state != 'running' and task_state != 'runnable'
group by wait_type, NormText
order by MaxWaitDuration descdeclare @minruntime2005 datetime, @maxruntime2005 datetime, @cpu_count int
select @minruntime2005 = min(runtime), @maxruntime2005 = MAX(runtime) from tbl_OS_WAIT_STATS
select @cpu_count = PropertyValue from tbl_ServerProperties where PropertyName = 'cpu_count'
select a.[wait_type], (b.[wait_time_ms]-a.[wait_time_ms]) TotalWait_ms_AcrossAllCPUs,
DATEDIFF(SECOND,a.runtime,b.runtime) PSSDIAGCollectionTimeMin, (b.[wait_time_ms]-a.[wait_time_ms])/(DATEDIFF(SECOND,a.runtime,b.runtime)*@cpu_count) WaitTime_ms_per_second_per_cpu,
case when a.[wait_type] in
('cxpacket', 'XE_DISPATCHER_WAIT', 'XE_TIMER_EVENT', 'REQUEST_FOR_DEADLOCK_SEARCH','WAITFOR', 'LOGMGR_QUEUE', 'CHECKPOINT_QUEUE',
'SLEEP_TASK', 'FT_IFTS_SCHEDULER_IDLE_WAIT', 'SLEEP_SYSTEMTASK', 'PREEMPTIVE_XE_DISPATCHER', 'SP_SERVER_DIAGNOSTICS_SLEEP', 'LAZYWRITER_SLEEP'
)
then 'IGNORE' End as Ignorable
from
(select * from tbl_OS_WAIT_STATS a where a.runtime = @minruntime2005) as a
inner join
(select * from tbl_OS_WAIT_STATS b where b.runtime =@maxruntime2005) as b
on a.[wait_type] = b.[wait_type]
order by TotalWait_ms_AcrossAllCPUs descselect sum(TotalDuration) Duration_ms, sum(TotalCPU) CPU_ms, sum(TotalReads) Reads, AppName
from ReadTrace.tblBatchPartialAggs b inner join
ReadTrace.tblUniqueAppNames a on a.iID = b.AppNameID
group by AppName
order by Duration_ms descdeclare @cpus int
select @cpus = PropertyValue from tbl_ServerProperties
where PropertyName = 'cpu_count'
select
t2.[name] as spinlock_name, cast(cast(t2.spins as float) - cast(t1.spins as float) as bigint) delta_spins,
cast (cast(t2.Backoffs as float) - cast (t1.Backoffs as float) as bigint) delta_backoff,
DATEDIFF(MI,t1.runtime,t2.runtime) delta_minuntes,
(cast(cast(t2.spins as float) - cast(t1.spins as float) as bigint) )/DATEDIFF(millisecond,t1.runtime,t2.runtime)/@cpusspins_per_millisecond_per_CPU
from
(select row_number () over ( partition by [name] order by runtime) row, * from [tbl_SPINLOCKSTATS] where runtime in (select min(runtime)
from tbl_spinlockstats) ) t1
join
(select row_number () over ( partition by [name] order by runtime) row, * from [tbl_SPINLOCKSTATS] where runtime in (select max(runtime)
from tbl_spinlockstats) ) t2
on t1.row = t2.row and t1.[name]=t2.[name]
order by delta_spins desc