要知道執行緒等待時間是制約sql server效率的重要原因,這乙個隨筆中將學習怎樣收集sql server中的執行緒等待時間,型別等資訊,這些資訊是進行資料庫優化的依據。
sys.dm_os_wait_stats
這是乙個系統檢視,裡面儲存執行緒所遇到的所有的等待資訊,具體的列如下表
列名
資料型別
說明
wait_type
nvarchar(60)
等待型別名稱
waiting_tasks_count
bigint
等待型別的等待數。該計數器在每開始乙個等待時便會增加。
wait_time_ms
bigint
該等待型別的總等待時間。
max_wait_time_ms
bigint
該等待型別的最長等待時間。
signal_wait_time_ms
bigint
正在等待的執行緒從收到訊號通知到開始執行之間的時差。
要注意的是,這個檢視的資訊每次關閉sql server的時候都會自動清除,下次開啟sql server的時候又會重新開始統計。
新建執行緒等待資訊表
如果想得到連續的資訊,在固定時間間隔內收集資訊比如乙個小時一次,這樣就可以分析系統分配的等待時間,識別出繁忙時間段。這裡我們將這些資訊收集到乙個資料表中儲存並進行分析。使用下面的語句新建乙個表:
use新建job填充資料要收集資訊最好是用乙個job來定時地執行insert語句填充資料,下面介紹步驟adventureworks
create
table
dbo.waitstats
(dt
datetime
notnull
default
(current_timestamp
),wait_type
nvarchar(60
) not
null
,waiting_tasks_count
bigint
notnull
,wait_time_ms
bigint
notnull
,max_wait_time_ms
bigint
notnull
,signal_wait_time_ms
bigint
notnull
);create
unique
clustered
index
idx_dt_type
ondbo.waitstats(dt, wait_type);
create
index
idx_type_dt
ondbo.waitstats(wait_type, dt);
點選資料庫中的sql server agent,展開,右擊jobs資料夾,右擊新建。如圖1
圖1在新建job介面,general標籤中填寫job名稱,描述,如圖2
圖2點選setps標籤,點選新建按鈕,在新建step介面內設定step name,type,database,command等屬性,如下圖3。這些屬性一看就知道是要做什麼的,就不一一的解釋了。還要說的 是截圖是建好的job,如果你自己做的話對話方塊顯示的標題可能不一樣。
圖3command屬性是設定要執行的sql語句或儲存過程等等,這裡設定如下的sql script:
insert點選shedules標籤,設定job的執行計畫,這裡設定的是每天的每5分鐘執行一次如圖4into
performance.dbo.waitstats
(wait_type, waiting_tasks_count, wait_time_ms,
max_wait_time_ms, signal_wait_time_ms)
select
wait_type, waiting_tasks_count, wait_time_ms,
max_wait_time_ms, signal_wait_time_ms
from
sys.dm_os_wait_stats
圖4上述步驟包含了新建乙個job的主要設定,其他的細節資訊沒有包含,遇到具體問題再具體分析吧。
收集等待資訊資料
過一段時間之後在表waitstats中就會有一些資料,每隔5分鐘就會在這個表中寫入一些資料,這些資料會不斷的增加。這裡為了得到相鄰間隔之間執行緒等待時間的變化就要使用自連線,連線條件是等待型別相同,當前行號等於上乙個的行號加上1,然後就可以用上一次等待時間減去這一次的等待時間得到這個變化值,下面使用乙個函式來實現這個邏輯:
if這個函式接受兩個引數,開始統計時間,結束統計時間,返回等待變化的時間,並按照型別排序。呼叫這個函式如下:object_id('
dbo.intervalwaits',
'if')
isnot
null
drop
function
dbo.intervalwaits;
gocreate
function
dbo.intervalwaits
(@fromdt
asdatetime
, @todt
asdatetime
)returns
table
asreturn
with
waits as(
select
dt, wait_type, wait_time_ms,
row_number()
over
(partition
bywait_type
order
bydt)
asrn
from
dbo.waitstats
)select
prv.wait_type, prv.dt
asstart_time,
cast
((cur.wait_time_ms
-prv.wait_time_ms)
/1000
. as
numeric(
12,
2))
asinterval_wait_s
from
waits
ascur
join
waits
asprv
oncur.wait_type
=prv.wait_type
andcur.rn
=prv.rn +1
andprv.dt
>=
@fromdt
andprv.dt
<
dateadd
(day, 1
, @todt)go
select wait_type, start_time, interval_wait_s
from dbo.intervalwaits('20110509', '20110510') as f
order by sum(interval_wait_s) over(partition by wait_type) desc,wait_type,start_time;
但是我們不能每次都去呼叫這個函式,所以可以吧這個查詢放在乙個檢視裡面,外部只需要使用檢視來查詢資料就可以了:
if從檢視中查詢得到的資料就是我們要得到的資料。但是這些並不明顯,先寫到這裡,下乙個隨筆我將在execl中把這些資料製作成乙個直方圖或者連線圖,橫軸是時間,縱軸是等待間隔時間。這樣就會更加直觀地看到在那些時間sql server的執行緒等待時間最長,也就是最繁忙的時候。object_id('
dbo.intervalwaitssample',
'v')
isnot
null
drop
view
dbo.intervalwaitssample;
gocreate
view
dbo.intervalwaitssample
asselect
wait_type, start_time, interval_wait_s
from
dbo.intervalwaits(
'20090212',
'20090215')
asf;
go
記錄點滴13
記錄點滴 13 2012年5 月27日星期日 大學二年級下學年第 14周結束 第 14周,又一周結束了,我再次提醒自己,最近過得不慍不火的,想學習的時候就學一下,想玩的時候就玩一下,想睡覺的時候就睡一下,每天還是堅持去上我怎麼感興趣的課程,越到後面課程慢慢上了,可以自己支配的時間多了,之前有課的時候...
Asio資料收集及使用點滴
asio的架構 boost.asio 設計索引 概念性了解api boost asio中的同步與非同步 asio的buffer buffer幾種用法,這些buffer都只是引用外部的記憶體資料,如果需要拷貝和分配,記得使用boost pool,這裡還有一篇處理拷貝buffer的文章 例子解析 boo...
專案需求收集過程的點滴
一 需求調研準備 在需求調研過程中,應該做好三種準備,保持兩種心態,做到五種提高 三種準備 1 調研前應該將所有專案前期資料進行彙總,與相關的前期銷售人員進行交流,以便對專案有乙個基本輪廓的認識。2 做好調研前使用資料的準備,如需求調研模板,需求調研問題列表等。3 做好不怕一切困難的準備。兩種心態 ...