sql server查詢語句阻塞優(yōu)化性能
在生產(chǎn)環(huán)境下,有時(shí)公司客服反映網(wǎng)頁半天打不到,除了在瀏覽器按F12的Network響應(yīng)來排查,確定web服務(wù)器無故障后。就需要檢查數(shù)據(jù)庫是否有出現(xiàn)阻塞
當(dāng)時(shí)數(shù)據(jù)庫的生產(chǎn)環(huán)境中主表數(shù)據(jù)量超過2000w,子表數(shù)據(jù)量超過1億,且更新和新增頻繁。再加上做了同步鏡像,很消耗資源。
這時(shí)就要新建一個(gè)會(huì)話,大概需要了解以下幾點(diǎn):
- 1.當(dāng)前活動(dòng)會(huì)話量有多少?
- 2.會(huì)話運(yùn)行時(shí)間?
- 3.會(huì)話之間有沒有阻塞?
- 4.阻塞時(shí)間 ?
查詢阻塞的方法有很多。有sql 2000 的sp_lock, 有sql 2005及以上的dmv
一. 阻塞查詢 sp_lock
執(zhí)行 exec sp_lock
下面列下關(guān)鍵字段
spid 是指進(jìn)程ID,這個(gè)過濾掉了系統(tǒng)進(jìn)程,只展示了用戶進(jìn)程spid>50。
dbid 指當(dāng)前實(shí)例下的哪個(gè)數(shù)據(jù)庫 , 使用DB_NAME() 函數(shù)來標(biāo)識(shí)數(shù)據(jù)庫
type 請求鎖住的模式
mode 鎖的請求狀態(tài)
- GRANT:已獲取鎖。
- CNVRT:鎖正在從另一種模式進(jìn)行轉(zhuǎn)換,但是轉(zhuǎn)換被另一個(gè)持有鎖(模式相沖突)的進(jìn)程阻塞。
- WAIT:鎖被另一個(gè)持有鎖(模式相沖突)的進(jìn)程阻塞。
總結(jié):當(dāng)mode 不為GRANT狀態(tài)時(shí), 需要了解當(dāng)前鎖的模式,以及通過進(jìn)程ID查找當(dāng)前sql 語句
例如當(dāng)前進(jìn)程ID是416,且mode狀態(tài)為WAIT 時(shí),查看方式 DBCC INPUTBUFFER(416)
用sp_lock查詢顯示的信息量很少,也很難看出誰被誰阻塞。所以當(dāng)數(shù)據(jù)庫版本為2005及以上時(shí)不建議使用。
二.阻塞查詢 dm_tran_locks
SELECT t1.resource_type, t1.resource_database_id, t1.resource_associated_entity_id, t1.request_mode, t1.request_session_id, t2.blocking_session_id FROM sys.dm_tran_locks as t1 INNER JOIN sys.dm_os_waiting_tasks as t2 ON t1.lock_owner_address = t2.resource_address;
上面查詢只顯示有阻塞的會(huì)話, 關(guān)注blocking_session_id 也就是被阻塞的會(huì)話ID,同樣使用DBCC INPUTBUFFER來查詢sql語句
三.阻塞查詢 sys.sysprocesses
SELECT spid, kpid, blocked, waittime AS 'waitms', lastwaittype, DB_NAME(dbid)AS DB, waitresource, open_tran, hostname,[program_name], hostprocess,loginame, [status] FROM sys.sysprocesses WITH(NOLOCK) WHERE kpid>0 AND [status]<>'sleeping' AND spid>50 AND spid<>@@SPID
sys.sysprocesses 能顯示會(huì)話進(jìn)程有多少, 等待時(shí)間, open_tran有多少事務(wù), 阻塞會(huì)話是多少. 整體內(nèi)容更為詳細(xì)。
關(guān)鍵字段說明:
- spid 會(huì)話ID(進(jìn)程ID),SQL內(nèi)部對一個(gè)連接的編號(hào),一般來講小于50
- kipid 線程ID
- blocked: 阻塞的進(jìn)程ID, 值大于0表示阻塞, 值為本身進(jìn)程ID表示io操作
- waittime:當(dāng)前等待時(shí)間(以毫秒為單位)。
- open_tran: 進(jìn)程的打開事務(wù)數(shù)
- hostname:建立連接的客戶端工作站的名稱
- program_name 應(yīng)用程序的名稱。
- hostprocess 工作站進(jìn)程 ID 號(hào)。
- loginame 登錄名。
- [status]
- running = 會(huì)話正在運(yùn)行一個(gè)或多個(gè)批
- background = 會(huì)話正在運(yùn)行一個(gè)后臺(tái)任務(wù),例如死鎖檢測
- rollback = 會(huì)話具有正在處理的事務(wù)回滾
- pending = 會(huì)話正在等待工作線程變?yōu)榭捎?/li>
- runnable = 會(huì)話中的任務(wù)在等待,由scheduler來運(yùn)行的可執(zhí)行隊(duì)列中。(重要)
- spinloop = 會(huì)話中的任務(wù)正在等待調(diào)節(jié)鎖變?yōu)榭捎谩?/li>
- suspended = 會(huì)話正在等待事件(如 I/O)完成。(重要)
- sleeping = 連接空閑
- wait resource 格式為 fileid:pagenumber:rid 如(5:1:8235440)
- kpid=0, waittime=0 空閑連接
- kpid>0, waittime=0 運(yùn)行狀態(tài)
- kpid>0, waittime>0 需要等待某個(gè)資源,才能繼續(xù)執(zhí)行,一般會(huì)是suspended(等待io)
- kpid=0, waittime=0 但它還是阻塞的源頭,查看open_tran>0 事務(wù)沒有及時(shí)提交。
如果blocked>0,但waittime時(shí)間很短,說明阻塞時(shí)間不長,不嚴(yán)重
如果status 上有好幾個(gè)runnable狀態(tài)任務(wù),需要認(rèn)真對待。 cpu負(fù)荷過重沒有及時(shí)處理用戶的并發(fā)請求
到此這篇關(guān)于sql server查詢語句阻塞優(yōu)化性能的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
限制MSSQL使用內(nèi)存的方法(針對內(nèi)存小的云主機(jī))
使用騰訊云Windows云服務(wù)器安裝SQL SERVER數(shù)據(jù)庫,在我們使用的過程中,有時(shí)候在任務(wù)管理器發(fā)現(xiàn)SQL SERVE的進(jìn)程占用很高的內(nèi)存和CPU,本文介紹如何限制SQL SERVER內(nèi)存占用2023-08-08Sqlserver中char,nchar,varchar與Nvarchar的區(qū)別分析
Sqlserver中char,nchar,varchar與Nvarchar的區(qū)別分析,使用sqlserver的朋友可以參考下。2011-08-08SQLServer存儲(chǔ)過程實(shí)現(xiàn)單條件分頁
本文主要介紹了SQLServer存儲(chǔ)過程實(shí)現(xiàn)單條件分頁的方法,具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-03-03清除SQL?Server數(shù)據(jù)庫日志(ldf文件)的方法匯總
隨著系統(tǒng)運(yùn)行時(shí)間的推移,數(shù)據(jù)庫日志文件會(huì)變得越來越大,這時(shí)我們需要對日志文件進(jìn)行備份或清理,這篇文章主要介紹了清除SQL?Server數(shù)據(jù)庫日志(ldf文件)的幾種方法,需要的朋友可以參考下2022-10-10SqlServer備份數(shù)據(jù)庫的4種方式介紹
這篇文章主要介紹了SqlServer備份數(shù)據(jù)庫的4種方式介紹,本文講解了用sqlserver的維護(hù)計(jì)劃、通過腳本+作業(yè)的方式備份數(shù)據(jù)庫(非xp_cmdshell和xp_cmdshell)、用powershell調(diào)用sqlcmd來執(zhí)行備份命令幾種方式,需要的朋友可以參考下2015-02-02深入SQL SERVER合并相關(guān)操作Union,Except,Intersect的詳解
本篇文章是對SQL SERVER合并相關(guān)操作Union,Except,Intersect進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06