在今天的文章里我想詳細談下SQL Server里的統計等待(Wait Statistics),還有她們如何幫助你立即為什么你的SQL Server當前很慢。一提到性能調優,對我來說統計等待是SQL Server了最重要的概念。
查詢為什么等待在SQL Server里每次你執行1個查詢,查詢總需要等待。什么?查詢總需要等待?是的,你沒有看錯:但給你執行1個查詢時,查詢總需要等待。為什么查詢需要等待的原因是SQL Server通過所謂的等待統計(Wait Statistics)來跟蹤的。在我進入等待統計(Wait Statistics)細節內容前,我想談下SQL Server里查詢總需要等待的原因。在SQL Server里查詢發生等待有2個原因:
我們來詳細看下這2類等待。當你等待外部資源時會發生資源等待(Resource Wait)。這里我想你一些例子。每次一個查詢從緩存池請求1個頁時,如果這個頁沒被緩存的話,緩存區管理器需要到你的存儲進行異步I/O操作,從你的物理存儲讀取頁到緩存池。而且訪問物理存儲會非常慢。由于這個原因SQL Server會拿掉你查詢的CPU周期,查詢只會等待直到異步I/O操作完成(同事其它查詢可以更有效的使用CPU資源)。最后你的查詢繼續它的執行。
當你需要獲取鎖時也會發生同樣的事情——當你想要讀或修改數據時。當其它人已經獲得了不兼容的鎖,你的查詢需要去等待直到鎖可以獲得。同時SQL Server會再次拿掉你的CPU周期,查詢需要去等待直到其它查詢的不兼容鎖釋放掉,這樣的話查詢本身可以獲得請求的鎖。
除資源等待外,SQL Server查詢還會因SQLOS(SQL Server操作系統(OS))內部實現的協同調度(Cooperative Scheduling)而等待。SQL Server繞過Windows系統的搶占式調度(Cooperative Scheduling),調度它的線程本身。因為這樣的設計SQL Server會更容易擴展,并為你提供更好的吞吐量。當1個查詢在CPU上積極運行時,SQL Server本身就可以決定,當1個查詢從CPU上拿掉時,SQL Server也可以決定,這樣的話另1個查詢可以在那個CPU上活躍繼續它的查詢執行。由于這個原因,一旦查詢溢出所謂的量(Quantum),SQL Server就會把你的查詢從CPU上拿掉。
量定義了查詢在CPU上可以活躍花費的時間片(time slice)。在SQL Server里這個時間片是4毫秒長。這就是說一旦查詢完成它的工作超出4毫秒,SQL Server就會把你的查詢從CPU上拿掉。因此在SQL Server里查詢總是要等待。如果沒有資源等待,溢出量就會踢入,查詢會在CPU上睡著(going off)。你的查詢總會等待!
查詢生命周期我們我們知道了在SQL Server里查詢總需要等待。我們來進一步看下它。當你執行1個查詢,這個查詢會進入3個不同的狀態,如下圖中所示:
我們來詳細說下這3個狀態。只要你的查詢在你的CPU上積極運行,這個查詢是在RUNNING狀態。RUNNING狀態意味著你的查詢當前正進行一些工作。進入這個狀態一直是你的首要目標。當SQL Server把你的查詢從CPU上拿掉時,然后這個查詢移入了SUSPENDED狀態。查詢只要SUSPENDED狀態需要都會等待,直到請求的資源可用(回想下從你物理存儲讀取的頁,或者不能立即獲得的不兼容鎖)。
當請求的資源可用時,然后SQL Server把你的查詢移入RUNNABLE狀態。RUNNABLE狀態意味著你的查詢準備好了繼續執行,但它需要另外必需的東西:在它上面運行的CPU。當現在沒有可用的CPU時(因為其它查詢當前在RUNNING狀態),查詢需要在RUNNABLE狀態花費一些時間。 最后當CPU變成可用時,查詢移入RUNNING狀態,然后一切輪回繼續。一個簡單的查詢在執行期間,可以運行上幾百次,甚至幾千次的查詢生命周期(query life cycle)。
分析等待統計(Wait Statistics)所有這些狀態事務被SQL Server跟蹤,并通過等待統計反饋給我們。SQL Server通過DMVsys.dm_os_wait_stats 來披露這些等待統計(Wait Statistics)。從這個DMV返回的每條記錄都是SQL Server里的1個等待原因。在SQL Server 2014里你共有771個不同的為什么查詢會等待的原因。什么?771個不同原因?跟我開玩笑吧?那是很多的!沒錯!但一般來說你只需要處理一些特定的等待原因,因為我們每個人幾乎都處理SQL Server里同樣的性能問題:
當在面前有一個運行慢的SQL Server,第一步我總看下等待統計里的詳細信息,因為它們告訴我為什么SQL Server里查詢在等待。但SQL Server里的等待統計只是個癥狀,不是問題根源本身!或許SQL Server通過等待統計告訴你在過去有一些因阻塞情形的等待。但可能是不是你有一個不好的索引設計,缺失了一個非常重要的非聚集索引導致了阻塞情形?有了額外的非聚集索引你提供SQL Server額外的數據訪問路徑,是否你的阻塞情形就可以輕松解決?這只是癥狀并非根源的1個例子(很多中的)。
小結在這個文章里我給你概況介紹了在SQL Server里為什么查詢會等待,還有這些等待如何通過等待統計來跟蹤。等待統計里最重要的事情是SQL Server里它只告訴你癥狀,并不是問題根源。作為故障排除人,你的工作是讀和理解統計等待,最后挖出你SQL Server里更多的信息來找出潛在的問題根源。
感謝關注!
新聞熱點
疑難解答