標籤:work read alt blog keyword 連續 substr with case when
死結和堵塞一直是效能測試執行中關注的重點。
下面是我整理的監控sql server資料庫,在效能測試過程中是否出現死結、堵塞的SQL語句,還算比較準備,留下來備用。
--每秒死結數量SELECT *FROM sys.dm_os_performance_countersWHERE counter_name LIKE ‘Number of Deadlocksc%‘;--查詢當前阻塞WITH CTE_SID ( BSID, SID, sql_handle ) AS ( SELECT blocking_session_id , session_id , sql_handle FROM sys.dm_exec_requests WHERE blocking_session_id <> 0 UNION ALL SELECT A.blocking_session_id , A.session_id , A.sql_handle FROM sys.dm_exec_requests A JOIN CTE_SID B ON A.SESSION_ID = B.BSID ) SELECT C.BSID , C.SID , S.login_name , S.host_name , S.status , S.cpu_time , S.memory_usage , S.last_request_start_time , S.last_request_end_time , S.logical_reads , S.row_count , q.text FROM CTE_SID C JOIN sys.dm_exec_sessions S ON C.sid = s.session_id CROSS APPLY sys.dm_exec_sql_text(C.sql_handle) Q ORDER BY sid
在壓力測試過程中,不間斷的按F5鍵執行上面的SQL語句,如果出現死結或者堵塞現象,就會在執行結果中羅列出來。如果每次連續執行SQL,都有死結或者堵塞出現,說明死結或者堵塞的比較嚴重。
查看SQLServer最耗資源時間的SQL語句執行最慢的SQL語句SELECT(total_elapsed_time / execution_count)/1000 N‘平均時間ms‘,total_elapsed_time/1000 N‘總花費時間ms‘,total_worker_time/1000 N‘所用的CPU總時間ms‘,total_physical_reads N‘物理讀取總次數‘,total_logical_reads/execution_count N‘每次邏輯讀次數‘,total_logical_reads N‘邏輯讀取總次數‘,total_logical_writes N‘邏輯寫入總次數‘,execution_count N‘執行次數‘,SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,((CASE statement_end_offsetWHEN -1 THEN DATALENGTH(st.text)ELSE qs.statement_end_offset END- qs.statement_start_offset)/2) + 1) N‘執行語句‘,creation_time N‘語句編譯時間‘,last_execution_time N‘上次執行時間‘FROMsys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) stWHERESUBSTRING(st.text, (qs.statement_start_offset/2) + 1,((CASE statement_end_offsetWHEN -1 THEN DATALENGTH(st.text)ELSE qs.statement_end_offset END- qs.statement_start_offset)/2) + 1) not like ‘?tch%‘ORDER BYtotal_elapsed_time / execution_count DESC; --總耗CPU最多的前個SQL:
SELECT TOP 20
total_worker_time/1000 AS [總消耗CPU 時間(ms)],execution_count [運行次數],
qs.total_worker_time/qs.execution_count/1000 AS [平均消耗CPU 時間(ms)],
last_execution_time AS [最後一次執行時間],max_worker_time /1000 AS [最大執行時間(ms)],
SUBSTRING(qt.text,qs.statement_start_offset/2+1,
(CASE WHEN qs.statement_end_offset = -1
THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset END -qs.statement_start_offset)/2 + 1)
AS [使用CPU的文法], qt.text [完整文法],
qt.dbid, dbname=db_name(qt.dbid),
qt.objectid,object_name(qt.objectid,qt.dbid) ObjectName
FROM sys.dm_exec_query_stats qs WITH(nolock)
CROSS apply sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE execution_count>1
ORDER BY total_worker_time DESC
--平均耗CPU最多的前個SQL:
SELECT TOP 20
total_worker_time/1000 AS [總消耗CPU 時間(ms)],execution_count [運行次數],
qs.total_worker_time/qs.execution_count/1000 AS [平均消耗CPU 時間(ms)],
last_execution_time AS [最後一次執行時間],min_worker_time /1000 AS [最小執行時間(ms)],
max_worker_time /1000 AS [最大執行時間(ms)],
SUBSTRING(qt.text,qs.statement_start_offset/2+1,
(CASE WHEN qs.statement_end_offset = -1
THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset END -qs.statement_start_offset)/2 + 1)
AS [使用CPU的文法], qt.text [完整文法],
qt.dbid, dbname=db_name(qt.dbid),
qt.objectid,object_name(qt.objectid,qt.dbid) ObjectName
FROM sys.dm_exec_query_stats qs WITH(nolock)
CROSS apply sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE execution_count>1
ORDER BY (qs.total_worker_time/qs.execution_count/1000) DESC
SQL SERVER 集合