sqlserver中幾種典型的等待
為了準備今年的雙11很久沒有更新blog,在最近的幾次sqlserver問題的排查中,總結了sqlserver幾種典型的等待類型,類似于oracle中的等待事件,如果看到這樣的等待類型時候能夠迅速定位問題的根源,下面通過一則案例來把這些典型的等待處理方法整理出來:
第一種等待.memory等待
早上接到一用戶反饋其RDS實例非常的慢,通過觀察sqlserver活動會話監(jiān)視器(active monitor)的waiting tasks(類似于mysql的thread running)可以看到有10多w的等待任務,可以明確數(shù)據(jù)庫現(xiàn)在已經(jīng)出現(xiàn)了較大的瓶頸,緊接著通過resource waits看到數(shù)據(jù)庫中有大量的memory內(nèi)存等待:

看到是memory 資源等待后,為了立刻恢復用戶應用,想到立刻去調(diào)大內(nèi)存,發(fā)現(xiàn)該實例已經(jīng)是24G了,看來一下os的空余內(nèi)存,還有較多的內(nèi)存剩余,所以將內(nèi)存調(diào)大到36G,發(fā)現(xiàn)resource waits還是在memory上等待,同時這個時候的cpu使用率飆升,達到了90%左右(之前在10%左右的等待).這樣解決不了根本問題,于是通過recent expensive queries,發(fā)現(xiàn)以下sql的邏輯讀很高,執(zhí)行非常頻繁:
SELECT * FROM RefundOrder_Message messages0_ WHERE messages0_.Order_Id=@p0;
也可以通過如下方式獲得造成內(nèi)存等待的sql:
SELECT st.text FROM sys.dm_exec_query_memory_grants req CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) as ST where req.grant_time is NULL or req.granted_memory_kb is NULL
The columns grant_time and granted_memory_kb will be NULL for those queries which are waiting to get their requested memory
sp_helpindex RefundOrder_Message
發(fā)現(xiàn)該表只有一個主鍵索引:

創(chuàng)建一下索引:
create index ind_RefundOrder_Message_order_id on RefundOrder_Message(Order_Id);

第二種等待:latch等待
在索引加上去后,memory的等待立刻消失,但是resource waits的等待變?yōu)榱?lock:

通過以下內(nèi)部視圖可以發(fā)現(xiàn)如下調(diào)用出現(xiàn)了等待:
SELECT ss.host_name, req.blocking_session_id,req.wait_type ,req.wait_time ,req.wait_resource ,req.transaction_id ,st.text FROM sys.dm_exec_requests req CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) as ST
cross apply sys.dm_exec_sessions ss where req.status =N'suspended' and ss.session_id=req.session_id;
得到阻塞其他會話的sql:
(@p0 int,@p1 nvarchar(4000),@p2 bit)
SELECT TOP (@p0) this.* FROM ViewSalesOrder this_ WHERE this_.MemberCode = @p1 and this_.IsObsolete = @p2 ORDER BY this_.OdCode desc;
視圖ViewSalesOrder是一張非常核心的視圖,里面關聯(lián)了訂單,訂單消息,訂單發(fā)貨等多個業(yè)務邏輯;查詢條件中代入了membercode為店鋪的名稱,可能操作某個店鋪的訂單;
通過ViewSalesOrder視圖中的定義,membercode,IsObsolete ,OdCode 為salesOrder表的三個字段,查看salesOrder上并沒有相應的索引,于是加上如下索引:
create index ind_salesOrder_member on salesOrder(membercode,IsObsolete,code);
在添加完索引后,數(shù)據(jù)庫的waiting tasks 下降,batch requests提升:

第三種等待:lock
第三種等待是常見的等待,常見的情況在刪除,更新的時候由于條件中沒有合適的索引導致鎖定的記錄范圍太大,導致阻塞其他的會話請求:
用戶在在進行壓測的時候發(fā)現(xiàn)一條更新語句執(zhí)行的非常慢,導致整個系統(tǒng)都卡?。?/p>

update DD_ShenHe set ZF = 0 where zf is null;
查看dd_shenhe表上面的索引:

可以看到表中并沒有zf字段的索引,而該表總共有400w的數(shù)據(jù),zf 為null的有8000條,所以在zf字段添加索引是合適的:
Create index ind_dd_shenhe_zf on dd_shenhe(zf);
添加完索引后,系統(tǒng)恢復正常。
相關文章
SQL?Server數(shù)據(jù)庫表的創(chuàng)建與管理操作大全
這篇文章主要給大家介紹了關于SQL?Server數(shù)據(jù)庫表的創(chuàng)建與管理操作的相關資料,?SQL?Server是一個關系型數(shù)據(jù)庫管理系統(tǒng),它可以幫助用戶創(chuàng)建、管理和查詢數(shù)據(jù),文中介紹的非常詳細,需要的朋友可以參考下2024-01-01
SqlServer2000+ 身份證合法校驗函數(shù)的示例代碼
這篇文章主要介紹了SqlServer2000+ 身份證合法校驗函數(shù),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
SQL?Server數(shù)據(jù)庫生成與執(zhí)行SQL腳本詳細教程
為了方便可以把需要連續(xù)執(zhí)行的SQL語句寫到一個文本文件中,并且用.SQL作為擴展名,這種文件叫做SQL腳本文件,下面這篇文章主要給大家介紹了關于SQL?Server數(shù)據(jù)庫生成與執(zhí)行SQL腳本的相關資料,需要的朋友可以參考下2023-01-01
SQL Server 2016 無域群集配置 AlwaysON 可用性組圖文教程
這篇文章主要介紹了SQL Server 2016 無域群集配置 AlwaysON 可用性組圖文教程,需要的朋友可以參考下2017-04-04
Sql檢驗數(shù)據(jù)庫中各個表的數(shù)據(jù)量
本文主要介紹了Sql檢驗數(shù)據(jù)庫中各個表的數(shù)據(jù)量,這樣的查詢有助于評估每個表的數(shù)據(jù)量,從而更好地進行數(shù)據(jù)庫性能優(yōu)化,具有一定的參考價值,感興趣的可以了解一下2023-12-12
完美解決SQL server2005中插入漢字變成問號的問題
以下是對在SQL server2005中插入漢字變成問號的解決辦法進行了分析介紹。需要的朋友可以過來參考下2013-08-08

