Tuning Performance
1. OS level:
SELECT wait_type, waiting_tasks_count, wait_time_ms, max_wait_time_ms, signal_wait_time_ms FROM sys.dm_os_wait_stats ORDER BY wait_type;
-- The DMV accumulates values since the server was last restarted. If you want to reset its values, run the following code
DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR);
signal_wait_time_ms:
The attribute signal_wait_time_ms indicates the time it took from the moment the thread is signaled that the resource is available until the thread gets CPU time and starts using the resource. As you can imagine, high values in this attribute typically indicate CPU problems.
2. More detail informaiton about the wait types which take up most of the wait time:
WITH Waits AS ( SELECT wait_type, wait_time_ms / 1000. AS wait_time_s, 100. * wait_time_ms / SUM(wait_time_ms) OVER() AS pct, ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn, 100. * signal_wait_time_ms / wait_time_ms as signal_pct FROM sys.dm_os_wait_stats WHERE wait_time_ms > 0 AND wait_type NOT LIKE N'%SLEEP%' AND wait_type NOT LIKE N'%IDLE%' AND wait_type NOT LIKE N'%QUEUE%' AND wait_type NOT IN( N'CLR_AUTO_EVENT' , N'REQUEST_FOR_DEADLOCK_SEARCH' , N'SQLTRACE_BUFFER_FLUSH' /* filter out additional irrelevant waits */ ) ) SELECT W1.wait_type, CAST(W1.wait_time_s AS NUMERIC(12, 2)) AS wait_time_s, CAST(W1.pct AS NUMERIC(5, 2)) AS pct, CAST(SUM(W2.pct) AS NUMERIC(5, 2)) AS running_pct, CAST(W1.signal_pct AS NUMERIC(5, 2)) AS signal_pct FROM Waits AS W1 JOIN Waits AS W2 ON W2.rn <= W1.rn GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct, W1.signal_pct HAVING SUM(W2.pct) - W1.pct < 80 -- percentage threshold OR W1.rn <= 5 ORDER BY W1.rn;
3. collect stats data with a job every 1 hour(or some other time)
USE Performance; IF OBJECT_ID('dbo.WaitStats', 'U') IS NOT NULL DROP TABLE dbo.WaitStats; CREATE TABLE dbo.WaitStats ( dt DATETIME NOT NULL DEFAULT (CURRENT_TIMESTAMP), wait_type NVARCHAR(60) NOT NULL, waiting_tasks_count BIGINT NOT NULL, wait_time_ms BIGINT NOT NULL, max_wait_time_ms BIGINT NOT NULL, signal_wait_time_ms BIGINT NOT NULL ); CREATE UNIQUE CLUSTERED INDEX idx_dt_type ON dbo.WaitStats(dt, wait_type); CREATE INDEX idx_type_dt ON dbo.WaitStats(wait_type, dt); -- Job step to collect data INSERT INTO Performance.dbo.WaitStats (wait_type, waiting_tasks_count, wait_time_ms, max_wait_time_ms, signal_wait_time_ms) SELECT wait_type, waiting_tasks_count, wait_time_ms, max_wait_time_ms, signal_wait_time_ms FROM sys.dm_os_wait_stats WHERE wait_type NOT IN (N'MISCELLANEOUS');