Skip to content

Poll SPID Performance

A script that polls a single SPID every second and breaks down its wait types, CPU and physical I/O until it sleeps.

Published Apr 30, 2009

Want to know exactly where one SPID spends its time? This script polls sysprocesses for a given session every second, accumulating samples of each wait type it encounters along with cumulative CPU and physical I/O - and stops when the session goes to sleep. The result is a per-wait-type breakdown plus total execution stats for that request's lifetime.

Set @SpidToMonitor at the top before running.

SET NOCOUNT ON;
GO
DECLARE @SpidToMonitor int = 137

DECLARE @WaitType varchar(128)
DECLARE @WaitTime int
DECLARE @Samples int = 0
DECLARE @Status varchar(128)
DECLARE @PreviousWaitType varchar(128) = ''
DECLARE @PreviousWaitTime int = 0
DECLARE @StartingCPU bigint
DECLARE @StartingPhysicalIO bigint
DECLARE @CPU bigint
DECLARE @PhysicalIO bigint

DECLARE @WaitStats table
(
	WaitType varchar(128),
	WaitTime int,
	Samples int
)

DECLARE @ExecStats table
(
	CPU bigint,
	PhysicalIO bigint,
	WaitTime bigint
)

SELECT
	@StartingCPU = cpu,
	@StartingPhysicalIO = physical_io
FROM
	sys.sysprocesses
WHERE
	spid = @SpidToMonitor

INSERT INTO @ExecStats(CPU, PhysicalIO) SELECT 0, 0

WHILE(1 = 1)
BEGIN--WHILE
	SELECT
		@WaitType = lastwaittype,
		@WaitTime = waittime,
		@CPU = cpu - @StartingCPU,
		@PhysicalIO = physical_io - @StartingPhysicalIO,
		@Status = RTRIM(LTRIM([status]))
	FROM
		sys.sysprocesses
	WHERE
		spid = @SpidToMonitor

	UPDATE @ExecStats SET CPU = @CPU, PhysicalIO = @PhysicalIO

	SET @Samples = IsNull(@Samples, 0) + 1

	IF(@WaitType != @PreviousWaitType OR @WaitTime < @PreviousWaitTime)
	BEGIN--IF
		IF(@PreviousWaitTime > 0)
		BEGIN--IF
			UPDATE @WaitStats SET Samples = Samples + @Samples, WaitTime = WaitTime + @PreviousWaitTime WHERE WaitType = @PreviousWaitType
			IF(@@ROWCOUNT = 0)
			BEGIN--IF
				INSERT INTO @WaitStats(Samples, WaitType, WaitTime) Values(@Samples, @PreviousWaitType, @PreviousWaitTime)
			END--IF
		END--IF

		SET @Samples = 0
	END--IF

	IF(@Status = 'sleeping')
	BEGIN--IF
		IF(@WaitTime > 0)
		BEGIN--IF
			UPDATE @WaitStats SET Samples = Samples + @Samples, WaitTime = WaitTime + @WaitTime WHERE WaitType = @WaitType
			IF(@@ROWCOUNT = 0)
			BEGIN--IF
				INSERT INTO @WaitStats(Samples, WaitType, WaitTime) Values(@Samples, @WaitType, @WaitTime)
			END--IF
		END--IF
	END--IF

	SET @PreviousWaitType = @WaitType
	SET @PreviousWaitTime = @WaitTime

	IF @Status = 'sleeping'
	BEGIN--IF
		BREAK
	END--IF

	WAITFOR DELAY '00:00:00:01'
END--WHILE

UPDATE @ExecStats SET WaitTime = (SELECT SUM(WaitTime) FROM @WaitStats)

SELECT * FROM @WaitStats
SELECT * FROM @ExecStats
An unhandled error has occurred. Reload 🗙