Troubleshooting High Disk Queue Depth in SQL Server

Introduction

This document helps to find and fix high disk queue depth problems in SQL Server. These issues can slow down the system. With the help of Foglight and SQL queries, we can check what is causing the problem and take steps to improve performance.

Step 1: Confirm High Disk Queue Depth in Foglight

Navigate to: Foglight > SQL Server > Resources > Disk

Check for consistent spikes in Disk Queue Depth metric (e.g., > 94)

Confirm affected volume(s) and duration of spikes

Step 2: Identify Top I/O Consuming Queries

— Top 10 queries by I/O usage

SELECT TOP 10 qs.total_logical_reads + qs.total_logical_writes AS TotalIO, qs.execution_count, qs.total_elapsed_time / qs.execution_count AS AvgDuration_ms, SUBSTRING(st.text, (qs.statement_start_offset/2)+1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END – qs.statement_start_offset)/2)+1) AS QueryText FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st ORDER BY TotalIO DESC;

 

Step 3: Monitor File-Level I/O Stats

— Check latency per file

SELECT DB_NAME(fs.database_id) AS DatabaseName, mf.physical_name, fs.io_stall_read_ms, fs.num_of_reads, fs.io_stall_write_ms, fs.num_of_writes, (fs.io_stall_read_ms / NULLIF(fs.num_of_reads, 0)) AS AvgReadLatency_ms, (fs.io_stall_write_ms / NULLIF(fs.num_of_writes, 0)) AS AvgWriteLatency_ms FROM sys.dm_io_virtual_file_stats(NULL, NULL) fs JOIN sys.master_files mf ON fs.database_id = mf.database_id AND fs.file_id = mf.file_id ORDER BY AvgReadLatency_ms DESC;

Step 4: Check Wait Stats for I/O-Related Waits

— Top waits to confirm PAGEIOLATCH_*, WRITELOG, etc.

SELECT TOP 10 wait_type, wait_time_ms/1000.0 AS WaitTime_sec, 100.0 * wait_time_ms / SUM(wait_time_ms) OVER() AS WaitPercentage, signal_wait_time_ms/1000.0 AS SignalWaitTime_sec FROM sys.dm_os_wait_stats WHERE wait_type NOT IN (‘CLR_SEMAPHORE’,’LAZYWRITER_SLEEP’,’RESOURCE_QUEUE’,’SLEEP_TASK’,’SLEEP_SYSTEMTASK’,’SQLTRACE_BUFFER_FLUSH’,’WAITFOR’,’LOGMGR_QUEUE’,’CHECKPOINT_QUEUE’,’REQUEST_FOR_DEADLOCK_SEARCH’,’XE_TIMER_EVENT’,’BROKER_TO_FLUSH’,’BROKER_TASK_STOP’,’CLR_MANUAL_EVENT’,’CLR_AUTO_EVENT’,’DISPATCHER_QUEUE_SEMAPHORE’,’FT_IFTS_SCHEDULER_IDLE_WAIT’,’XE_DISPATCHER_WAIT’,’XE_DISPATCHER_JOIN’,’SQLTRACE_INCREMENTAL_FLUSH_SLEEP’,’WAIT_XTP_HOST_WAIT’) ORDER BY WaitTime_sec DESC;

Step 5: Take Action Based on Findings

Query Tuning:

Rewrite inefficient queries (e.g., full table scans, missing indexes)

Avoid large sorts/spools/tempdb usage

Indexing:

Add or adjust indexes based on execution plan

Storage Improvements:

Move hot files to faster storage (SSD/NVMe)

Scale up IOPS or throughput via storage tiering

TempDB Optimization:

Ensure multiple data files (8 recommended for >8 CPUs)

Monitor for tempdb contention

Conclusion

By following these steps, we can solve high disk queue depth issues and make SQL Server run faster. Regular checks and proper tuning will help keep the system healthy and responsive.

Recent Posts

Start typing and press Enter to search