性能調優9:根據WaitType診斷性能

SQL Server數據庫接收到查詢請求,從生成計劃到執行計劃的過程,等待次數和等待時間在一定程度上揭示了系統性能的壓力,如果資源嚴重不足,就會成爲性能的瓶頸。因此,對等待的監控非常有助於對系統性能進行診斷,對查詢語句進行性能調優。偶爾一次的異常等待,不足以表明系統存在瓶頸,但是,SQL Server實例經常出現特定的等待類型,並且等待時間趨於增加,這就說明,系統存在壓力,或內存,或IO等,根據WaitType對系統進行監控和診斷,還能對查詢進行性能調優,例如,Lock等待表明執行查詢存在數據競爭,PageIOLatch等待表明IO響應緩慢,PageLatch等待表明文件的佈局需要改進等。

一,查看等待信息

本文分享常用的等待類型及其產生的原因,通常使用DMV來查看等待:

  • sys.dm_exec_requests  來查看系統當前正在處理的請求,
  • sys.dm_os_wait_stats 統計當前系統發生過的等待的信息
  • sys.dm_os_waiting_tasks 查看當前正處於等待狀態的task

1,等待信息統計

SQL Server 保存了從上一次服務器啓動或者手動清空之後累計的等待信息,總的來說,等待類型分爲三類:資源等待,隊列等待和外部等待,在日常使用中,通常會過濾掉系統相關的等待類型,因爲這些等待對診斷性能瓶頸沒有多大用處,同時還過濾掉等待時間爲0的類型,腳本見文末的附言。

2,清空等待信息統計

對於生成環境,如果需要收集等待信息,那麼最好把等待信息清0,然後重新開始計數,通常使用DBCC SQPERF()命令來實現:

DBCC SQLPERF('sys.dm_os_wait_stats',clear)

二,資源信號(RESOURCE SEMAPHORE)

RESOURCE_SEMAPHORE 等待類型表示一個Workder等待SQL Server給予其申請的內存,以便執行Hash和Sort等操作。

1,RESOURCE_SEMAPHORE 揭示內存壓力

當出現 RESOURCE_SEMAPHORE 等待時,這說明查詢語句向系統請求的內存沒有得到滿足,就是說,該查詢語句在執行Task前,需要一定量的內存資源,如果SQL Server當前的內存不足,不能分配查詢語句請求的內存,將導致查詢語句處於等待內存資源的狀態。在SQL Server存儲引擎中,排序(Sort)操作和哈希(Hash)操作是非常消耗內存資源的兩個操作,優化相應的查詢語句,以減少這兩個操作,可以緩解SQL Server的內存壓力,但在SQL Server實例中,經常出現RESOURCE_SEMAPHORE 等待,這說明SQL Server存在內存壓力。

在數據庫中有一個選項,Min Memory Per Query,該選項表示SQL Server爲每個查詢分配的最小內存,這意味着,當一個查詢需要額外的內存資源,該查詢獲取的內存大小,很大部分是由該選項決定的,只有爲每個查詢授予一定的內存之後,該查詢語句纔會真正開始執行。

2,發送RESOURCE SEMAPHORE用於授予請求內存(Requested Memory)

當SQL Server實例收到用戶的查詢請求時,SQL Server優化器首先創建編譯計劃(Complied Plan),根據編譯計劃再創建執行計劃(Execution Plan)。當SQL Server優化器創建編譯計劃時,它需要計算查詢在執行時需要消耗的內存,用於執行查詢的內存分爲必需內存(Required Memory)和額外內存(Additional Memory)。必需內存是指SQL Server實例執行Sort或Hash操作時必須分配的最小內存,如果沒有分配必需內存,查詢請求不會執行。額外內存是查詢用於存儲臨時的中間數據的內存,如果SQL Server沒有足夠的內存,查詢將臨時數據存儲在硬盤中,這會降低查詢性能。

SQL Server 要授予每個查詢多少內存,查詢才能真正開始執行呢?

  • Step1,計算需要的內存(Needed Memory):SQL Server計算每個查詢需要多少內存才能執行,這通常是必需內存和額外內存之和,當查詢請求以併發方式執行時,需要的內存公式是:(RequiredMemory*DOP)+額外內存。
  • Step2,計算請求的內存(Requested Memory):SQL Server檢查每個查詢請求需要的內存數量是否超出系統的限制,SQL Server減少額外內存的數量,以致於不會超出系統的上限,這個最終的內存數量是查詢語句得以執行的請求內存。
  • Step3,爲查詢分配請求內存:SQL Server實例發送資源信號(RESOURCE SEMAPHORE),爲查詢(Query)授予/分配請求的物理內存。

當資源信號發送之後,如果SQL Server實例不能被授予查詢的請求內存,那麼查詢將處於RESOURCE_SEMAPHORE 等待狀態。SQL Server維護一個先入先出( first-come-first-served)的等待隊列,當新的查詢處於RESOURCE_SEMAPHORE 等待狀態,SQL Server將該查詢放入隊列的末尾。一旦SQL Server實例找到足夠的空閒內存,那麼SQL Server取出RESOURCE_SEMAPHORE 等待隊列頂端的第一個查詢,立即授予其請求的內存;該查詢獲得請求內存之後,開始執行查詢任務;如果SQL Server實例長時間有查詢處於RESOURCE_SEMAPHORE等待狀態,說明SQL Server 面臨內存壓力。

三,調度相關的等待

CXPACKET等待:發生在多任務系統中,用於表示併發執行的子線程在等待其他子線程的完成。

SOS_SCHEDULER_YIELD 等待:當前任務正在執行,但是其主動退讓調度程序上的時間片(time slicer),供其他進程使用,自己在後臺執行任務。

THREADPOOL 等待:查詢正在等待可用的Worker線程,可能出現了大量的並行計劃,以至於用完了系統可用的Worker。

DISPATCHER_QUEUE_SEMAPHORE等待:發生當一個進程(Thread)等待處理更多的Work時,也就是說,一個Thread處於空閒狀態,等待調度去工作。如果等待時間增加,說明調度器(Dispatcher)非常空閒;該WaitType不會成爲競爭資源,而將其他事務阻塞,在做Wait統計分析,可以過濾掉。

四,IO相關的等待

IO相關的等待與IO資源有關,比如,備份和還原等待的等待類型是:BACKUPIO/BACKUPBUFFER,這類等待發生在備份任務正在等待所需的數據或者數據緩存時。

1,異步網絡IO(ASYNC_NETWORK_IO)

ASYNC_NETWORK_IO等待類型發生在網絡不能及時把數據寫入到客戶端中。

SQL Server 產生的結果集需要經過網絡(Network)傳遞到客戶端(Client),如果網絡不能及時將結果集傳輸到Client,導致結果集仍然駐留在SQL Server的會話(Session)中,就會發生ASYNC_NETWORK_IO 等待,也就是說,ASYNC_NETWORK_IO 等待狀態出現在SQL Server已經把數據準備好,但是網絡發送速度跟不上,導致SQLServer返回的數據集仍然駐留在Session中,出現這種等待一般不是數據庫的問題,調整數據庫配置不會有大的幫助,網絡層的瓶頸當然是一個可能的原因,對此要考慮是否真有必要返回那麼多數據?所以,檢查應用程序是否有必要向SQL Server申請這麼大的結果集。

This wait type is where SQL Server has sent some data to a client through TDS and is waiting for the client to acknowledge that is has consumed the data, and can also show up with transaction replication if the Log Reader Agent job is running slowly for some reason.

2,異步IO完成(ASYNC_IO_COMPLETION)

ASYNC_IO_COMPLETION:當Task正在等待IO完成時發生,長時間的 ASYNC_IO_COMPLETION 等待經常發生在SQL Server正在執行數據庫備份和還原操作(執行Backup database 命令和 Restore 命令)時,查看《ASYNC_IO_COMPLETION》瞭解更多。

3,同步IO完成(IO_COMPLETION)

同步IO完成,此等待類型發生表示SQL Server正在等待IO操作的完成,通常用於表示非數據頁的IO操作,也就是說,文件的各種同步讀寫操作都與表數據無關,出現該等待,說明SQL Server很有可能正在做下面列出的動作:

  • 正在從事務日誌文件中讀取事務日誌
  • 正在讀取非數據頁,可能是管理頁(例如,GAM,SGAM,PFS等),經常發生在數據庫還原,DB啓動和恢復操作中。
  • 正在把排序的中間結果集寫入到硬盤
  • 在Merge Join操作中,正在讀寫合併的結果集
  • 在Eager Spool操作中,正在把數據集寫入到硬盤

在發生CXPACKET等待時,如果會話(Session)的數據IO(Logical Read/Write, Physical Read)都沒有變化,那麼,該會話很可能正在處理非數據頁的IO操作。IO_COMPLETION等待通常用於表示非數據頁的IO操作,例如,事務日誌的還原操作,讀取系統數據頁(GAM)等。通常來說,減少IO_COMPLETION 等待的方法有兩種:一是將IO分散到不同的Physical Disk上,一是減少對非數據頁的IO操作。

通常情況下,CXPACKET等待和IO_COMPLETION等待會同時發生,利用 sys.dm_os_waiting_tasks 查看當前處於等待狀態的Task,發現有一些Task 處於 IO_COMPLETION 等待,這說明,會話(Session)發生CXPACKET等待,是因爲在SQL Server以並行方式執行Task,有一些 Task執行速度慢,有些Task執行速度快,導致執行速度快的task完成之後,等待還未完成的Task;而執行速度慢的Task正在執行非數據頁IO。

4,WriteLog(寫事務日誌到硬盤)

和Disk的寫速度有關,說明任務當前正在等待將日誌記錄寫入日誌文件,出現這個等待狀態,意味着Disk的寫入速度是性能瓶頸。

五,Latch等待

Latch是一個輕量級的同步機制,用於在Thread嘗試讀取或修改數據時,使得Thread之間的數據保持同步。SQL Server共有三種類型的Latch等待:

  • PAGEIOLATH_XX:作用於數據頁(Data Page),發生在從硬盤讀取數據到內存時
  • PAGELATCH_XX:作用於已經存在於內存中的數據頁(Data Page)
  • LATCH_XX:作用於非頁(non-page)的數據結構

1,PageIOLatch(硬盤數據頁相關的IO)

當緩存在buffer pool 的data page 和disk 上數據文件裏的data page 進行交互時,爲了保證不會有多個用戶同時 read/write 內存中的buffer(a data page in memory),需要對buffer 加上PageIOLatch。PageIOLatch 是和 IO 有關,或從disk將Data page讀取到內存,或從內存將Data page寫入到disk。

  • PageIOLatch主要分爲兩大類:PageIOLatch_SH和PageIOLatch_EX
  • PageIOLatch_SH:發生在將一個Data Page從Disk 讀取到內存 buffer pool 中時。當用戶需要訪問一個Data Page,而這個Data Page不在內存中時,SQL Server 需要將 Data page 從Disk 讀取到內存中,這說明內存不夠大,或內存緊張,導致沒有將Data Page始終緩存在內存中,SQL Server 需要過多地Page Read(從Disk讀取Data page到內存 buffer pool)操作。這種情況說明內存是bottleneck。
  • PageIOLatch_EX:發生在用戶對內存中的Data page進行了修改,SQL Server需要寫回Disk,意味着disk的寫入速度慢。

2,PageLatch(內存數據頁相關的IO)

PageLatch 是對內存中的buffer(a data page in memory)加鎖,用於同步內存 buffer Pool中的Data Page數據修改操作。當一個task需要修改 buffer時,必須申請PageLatch_EX。只有得到這個Latch,才能修改buffer裏的內存。

由於buffer的修改都是在memory中完成的,所以每次修改的時間都應該非常短,而PageLatch只是在修改的過程中才會短暫出現。如果出現PageLatch等待,說明大量的併發語句在修改table,而修改操作同時集中在同一個page,或者數量不多的幾個page上,這些Page 稱作Hot Page。出現Hot Page 是由於數據過於集中導致,將數據分佈在不同的Files上,能夠減少PageLatch Wait。

3,Lacth等待

LATCH等待發生在一個線程整等待訪問一個非數據頁(Non-Data Page)的結構,該線程無法訪問該數據結構,是因爲其他的線程正在互斥模式下佔用它。

LATCH_EX This wait type occurs when a thread is waiting for access to a non-page data structure so that it can modify the data structure. The thread cannot get access to the data structure because one or more other threads have it latched in share mode. The Latches Whitepaper in the sidebar on the right has a description of all latch modes and their compatibility with other latch modes.

Non-Page的Latch等待對應於LATCH_SH 和 LATCH_EX, sys.dm_os_wait_stats 不會確切顯示哪一個Latch是爭用點。您可以在sys.dm_os_waiting_tasks DMV中查看實時發生的鎖存等待,DMV將顯示正在等待的鎖存器的名稱。 或者,您可以查看sys.dm_os_latch_stats DMV以查看哪些鎖存器具有最大的聚合爭用。

參考文檔:Most common latch classes and what they mean

4,FGCB_ADD_REMOVE閂鎖

FGCB代表File Group Control Block,當從文件組中增加或刪除文件時,或者當文件組中的文件增長或收縮(file)時,對文件組控制塊(FGCB)加閂鎖時會出現這類等待。最常發生在文件發生大量的自動增長,也可能來自擁有大量文件的文件組中,例如tempdb的主文件組(Primary FileGroup),當有大量的併發連接需要創建臨時表,這會導致tempdb的文件持續不斷的增長。對於這類問題,可以做好前期規劃,增加文件自動增長的容量,以免頻繁增長。

5,ACCESS_METHOD_XX (訪問方法)

ACCESS_METHOD_DATASET_PARENT和ACCESS_METHOD_SCAN_RANGE_GENERATOR:發生在並行掃描操作時,在並行掃描期間使用這兩個鎖存器爲每個線程提供一系列要掃描的頁面ID,對於這兩個等待,應查看是否存在大量掃描和HASH操作。

ACCESS_METHODS_HOBT_COUNT:此鎖存器用於將HoBt(Heap或B-Tree)的頁和行計數增量刷新到存儲引擎元數據表。 爭用將指示有大量的,小型併發DML操作作用於單表。

ACCESS_METHOD_HOBT_VIRTUAL_ROOT:通常發生在頁的根節點分裂時,此鎖存器用於訪問包含索引根頁面(Root Page)的頁面ID(Page ID)的元數據。 當B樹的根頁面發生分割(需要在EX模式下鎖存)時,如果線程想要沿B樹向下導航(需要在SH模式下的鎖存器)時,那麼線程必須等待,此時可能發生對該鎖存器的爭用。 這種等待可能是由於大量併發連接作用於小索引時出現,或者來自隨機鍵值的頁面拆分導致級聯頁面拆分(從葉子到根)。對於這個等待,應查看是否存在大量頁分裂的索引。

六,鎖管理器等待(LCK_M_**)

LCK_M_** 等待是Thread正在等待獲取鎖產生,表明系統產生阻塞問題,一般情況下,是由於編程質量差的查詢語句造成的,鎖升級,或長時間的IO操作,也會使Task長時間持有鎖,產生LCK_M_** 等待。

  • LCK_M_IS:當Task正在等待獲取意向鎖(IS,Intent Shared)時發生
  • LCK_M_U:當Task正在等待獲取更新鎖(U,Update)時發生

 

附言:下面的腳本用於描述等待的統計數據:

複製代碼

-- Last updated September 25, 2018
WITH [Waits] AS
(
    SELECT
        [wait_type],
        [wait_time_ms] / 1000.0 AS [WaitS],
        ([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
        [signal_wait_time_ms] / 1000.0 AS [SignalS],
        [waiting_tasks_count] AS [WaitCount],
        100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage],
        ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum]
    FROM sys.dm_os_wait_stats
    WHERE [wait_type] NOT IN (
        -- These wait types are almost 100% never a problem and so they are
        -- filtered out to avoid them skewing the results. Click on the URL
        -- for more information.
        N'BROKER_EVENTHANDLER', -- https://www.sqlskills.com/help/waits/BROKER_EVENTHANDLER
        N'BROKER_RECEIVE_WAITFOR', -- https://www.sqlskills.com/help/waits/BROKER_RECEIVE_WAITFOR
        N'BROKER_TASK_STOP', -- https://www.sqlskills.com/help/waits/BROKER_TASK_STOP
        N'BROKER_TO_FLUSH', -- https://www.sqlskills.com/help/waits/BROKER_TO_FLUSH
        N'BROKER_TRANSMITTER', -- https://www.sqlskills.com/help/waits/BROKER_TRANSMITTER
        N'CHECKPOINT_QUEUE', -- https://www.sqlskills.com/help/waits/CHECKPOINT_QUEUE
        N'CHKPT', -- https://www.sqlskills.com/help/waits/CHKPT
        N'CLR_AUTO_EVENT', -- https://www.sqlskills.com/help/waits/CLR_AUTO_EVENT
        N'CLR_MANUAL_EVENT', -- https://www.sqlskills.com/help/waits/CLR_MANUAL_EVENT
        N'CLR_SEMAPHORE', -- https://www.sqlskills.com/help/waits/CLR_SEMAPHORE
        N'CXCONSUMER', -- https://www.sqlskills.com/help/waits/CXCONSUMER
 
        -- Maybe comment these four out if you have mirroring issues
        N'DBMIRROR_DBM_EVENT', -- https://www.sqlskills.com/help/waits/DBMIRROR_DBM_EVENT
        N'DBMIRROR_EVENTS_QUEUE', -- https://www.sqlskills.com/help/waits/DBMIRROR_EVENTS_QUEUE
        N'DBMIRROR_WORKER_QUEUE', -- https://www.sqlskills.com/help/waits/DBMIRROR_WORKER_QUEUE
        N'DBMIRRORING_CMD', -- https://www.sqlskills.com/help/waits/DBMIRRORING_CMD
 
        N'DIRTY_PAGE_POLL', -- https://www.sqlskills.com/help/waits/DIRTY_PAGE_POLL
        N'DISPATCHER_QUEUE_SEMAPHORE', -- https://www.sqlskills.com/help/waits/DISPATCHER_QUEUE_SEMAPHORE
        N'EXECSYNC', -- https://www.sqlskills.com/help/waits/EXECSYNC
        N'FSAGENT', -- https://www.sqlskills.com/help/waits/FSAGENT
        N'FT_IFTS_SCHEDULER_IDLE_WAIT', -- https://www.sqlskills.com/help/waits/FT_IFTS_SCHEDULER_IDLE_WAIT
        N'FT_IFTSHC_MUTEX', -- https://www.sqlskills.com/help/waits/FT_IFTSHC_MUTEX
 
        -- Maybe comment these six out if you have AG issues
        N'HADR_CLUSAPI_CALL', -- https://www.sqlskills.com/help/waits/HADR_CLUSAPI_CALL
        N'HADR_FILESTREAM_IOMGR_IOCOMPLETION', -- https://www.sqlskills.com/help/waits/HADR_FILESTREAM_IOMGR_IOCOMPLETION
        N'HADR_LOGCAPTURE_WAIT', -- https://www.sqlskills.com/help/waits/HADR_LOGCAPTURE_WAIT
        N'HADR_NOTIFICATION_DEQUEUE', -- https://www.sqlskills.com/help/waits/HADR_NOTIFICATION_DEQUEUE
        N'HADR_TIMER_TASK', -- https://www.sqlskills.com/help/waits/HADR_TIMER_TASK
        N'HADR_WORK_QUEUE', -- https://www.sqlskills.com/help/waits/HADR_WORK_QUEUE
 
        N'KSOURCE_WAKEUP', -- https://www.sqlskills.com/help/waits/KSOURCE_WAKEUP
        N'LAZYWRITER_SLEEP', -- https://www.sqlskills.com/help/waits/LAZYWRITER_SLEEP
        N'LOGMGR_QUEUE', -- https://www.sqlskills.com/help/waits/LOGMGR_QUEUE
        N'MEMORY_ALLOCATION_EXT', -- https://www.sqlskills.com/help/waits/MEMORY_ALLOCATION_EXT
        N'ONDEMAND_TASK_QUEUE', -- https://www.sqlskills.com/help/waits/ONDEMAND_TASK_QUEUE
        N'PARALLEL_REDO_DRAIN_WORKER', -- https://www.sqlskills.com/help/waits/PARALLEL_REDO_DRAIN_WORKER
        N'PARALLEL_REDO_LOG_CACHE', -- https://www.sqlskills.com/help/waits/PARALLEL_REDO_LOG_CACHE
        N'PARALLEL_REDO_TRAN_LIST', -- https://www.sqlskills.com/help/waits/PARALLEL_REDO_TRAN_LIST
        N'PARALLEL_REDO_WORKER_SYNC', -- https://www.sqlskills.com/help/waits/PARALLEL_REDO_WORKER_SYNC
        N'PARALLEL_REDO_WORKER_WAIT_WORK', -- https://www.sqlskills.com/help/waits/PARALLEL_REDO_WORKER_WAIT_WORK
        N'PREEMPTIVE_XE_GETTARGETSTATE', -- https://www.sqlskills.com/help/waits/PREEMPTIVE_XE_GETTARGETSTATE
        N'PWAIT_ALL_COMPONENTS_INITIALIZED', -- https://www.sqlskills.com/help/waits/PWAIT_ALL_COMPONENTS_INITIALIZED
        N'PWAIT_DIRECTLOGCONSUMER_GETNEXT', -- https://www.sqlskills.com/help/waits/PWAIT_DIRECTLOGCONSUMER_GETNEXT
        N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP', -- https://www.sqlskills.com/help/waits/QDS_PERSIST_TASK_MAIN_LOOP_SLEEP
        N'QDS_ASYNC_QUEUE', -- https://www.sqlskills.com/help/waits/QDS_ASYNC_QUEUE
        N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP',
            -- https://www.sqlskills.com/help/waits/QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP
        N'QDS_SHUTDOWN_QUEUE', -- https://www.sqlskills.com/help/waits/QDS_SHUTDOWN_QUEUE
        N'REDO_THREAD_PENDING_WORK', -- https://www.sqlskills.com/help/waits/REDO_THREAD_PENDING_WORK
        N'REQUEST_FOR_DEADLOCK_SEARCH', -- https://www.sqlskills.com/help/waits/REQUEST_FOR_DEADLOCK_SEARCH
        N'RESOURCE_QUEUE', -- https://www.sqlskills.com/help/waits/RESOURCE_QUEUE
        N'SERVER_IDLE_CHECK', -- https://www.sqlskills.com/help/waits/SERVER_IDLE_CHECK
        N'SLEEP_BPOOL_FLUSH', -- https://www.sqlskills.com/help/waits/SLEEP_BPOOL_FLUSH
        N'SLEEP_DBSTARTUP', -- https://www.sqlskills.com/help/waits/SLEEP_DBSTARTUP
        N'SLEEP_DCOMSTARTUP', -- https://www.sqlskills.com/help/waits/SLEEP_DCOMSTARTUP
        N'SLEEP_MASTERDBREADY', -- https://www.sqlskills.com/help/waits/SLEEP_MASTERDBREADY
        N'SLEEP_MASTERMDREADY', -- https://www.sqlskills.com/help/waits/SLEEP_MASTERMDREADY
        N'SLEEP_MASTERUPGRADED', -- https://www.sqlskills.com/help/waits/SLEEP_MASTERUPGRADED
        N'SLEEP_MSDBSTARTUP', -- https://www.sqlskills.com/help/waits/SLEEP_MSDBSTARTUP
        N'SLEEP_SYSTEMTASK', -- https://www.sqlskills.com/help/waits/SLEEP_SYSTEMTASK
        N'SLEEP_TASK', -- https://www.sqlskills.com/help/waits/SLEEP_TASK
        N'SLEEP_TEMPDBSTARTUP', -- https://www.sqlskills.com/help/waits/SLEEP_TEMPDBSTARTUP
        N'SNI_HTTP_ACCEPT', -- https://www.sqlskills.com/help/waits/SNI_HTTP_ACCEPT
        N'SOS_WORK_DISPATCHER', -- https://www.sqlskills.com/help/waits/SOS_WORK_DISPATCHER
        N'SP_SERVER_DIAGNOSTICS_SLEEP', -- https://www.sqlskills.com/help/waits/SP_SERVER_DIAGNOSTICS_SLEEP
        N'SQLTRACE_BUFFER_FLUSH', -- https://www.sqlskills.com/help/waits/SQLTRACE_BUFFER_FLUSH
        N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP', -- https://www.sqlskills.com/help/waits/SQLTRACE_INCREMENTAL_FLUSH_SLEEP
        N'SQLTRACE_WAIT_ENTRIES', -- https://www.sqlskills.com/help/waits/SQLTRACE_WAIT_ENTRIES
        N'WAIT_FOR_RESULTS', -- https://www.sqlskills.com/help/waits/WAIT_FOR_RESULTS
        N'WAITFOR', -- https://www.sqlskills.com/help/waits/WAITFOR
        N'WAITFOR_TASKSHUTDOWN', -- https://www.sqlskills.com/help/waits/WAITFOR_TASKSHUTDOWN
        N'WAIT_XTP_RECOVERY', -- https://www.sqlskills.com/help/waits/WAIT_XTP_RECOVERY
        N'WAIT_XTP_HOST_WAIT', -- https://www.sqlskills.com/help/waits/WAIT_XTP_HOST_WAIT
        N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG', -- https://www.sqlskills.com/help/waits/WAIT_XTP_OFFLINE_CKPT_NEW_LOG
        N'WAIT_XTP_CKPT_CLOSE', -- https://www.sqlskills.com/help/waits/WAIT_XTP_CKPT_CLOSE
        N'XE_DISPATCHER_JOIN', -- https://www.sqlskills.com/help/waits/XE_DISPATCHER_JOIN
        N'XE_DISPATCHER_WAIT', -- https://www.sqlskills.com/help/waits/XE_DISPATCHER_WAIT
        N'XE_TIMER_EVENT' -- https://www.sqlskills.com/help/waits/XE_TIMER_EVENT
        )
    AND [waiting_tasks_count] > 0
    AND [wait_time_ms] > 0
    )
SELECT
    MAX ([W1].[wait_type]) AS [WaitType],
    CAST (MAX ([W1].[WaitS]) AS DECIMAL (16,2)) AS [Wait_S],
    CAST (MAX ([W1].[ResourceS]) AS DECIMAL (16,2)) AS [Resource_S],
    CAST (MAX ([W1].[SignalS]) AS DECIMAL (16,2)) AS [Signal_S],
    MAX ([W1].[WaitCount]) AS [WaitCount],
    CAST (MAX ([W1].[Percentage]) AS DECIMAL (5,2)) AS [Percentage],
    CAST ((MAX ([W1].[WaitS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgWait_S],
    CAST ((MAX ([W1].[ResourceS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgRes_S],
    CAST ((MAX ([W1].[SignalS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgSig_S],
    CAST ('https://www.sqlskills.com/help/waits/' + MAX ([W1].[wait_type]) as XML) AS [Help/Info URL]
FROM [Waits] AS [W1]
INNER JOIN [Waits] AS [W2] ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum]
HAVING SUM ([W2].[Percentage]) - MAX( [W1].[Percentage] ) < 95; -- percentage threshold
GO

複製代碼

 

 

 

參考文檔:

The SQL Server Wait Type Repository…

Wait statistics, or please tell me where it hurts

Causes of IO_COMPLETION and WRITE_COMPLETION SQL Server wait types

SQL SERVER – IO_COMPLETION – Wait Type – Day 10 of 28

DISPATCHER_QUEUE_SEMAPHORE

Troubleshooting SQL Server RESOURCE_SEMAPHORE Waittype Memory Issues

LATCH_EX

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章