CPU性能瓶頸能夠從計數器 Processor:%Processor .若是這個很高,還要再檢查sql server的Process:%processor Time是否也很高,以肯定是不是sql server消耗的算法
CPU.sql
CPU高的緣由:併發
1.過分編譯和重編譯app
2.排序和聚合計算oop
3.表格鏈接操做性能
4.低效的執行計劃優化
5.並行查詢線程
過分編譯和重編譯server
編譯是sql server爲指令生成執行計劃的過程。分析指令要作的事情,分析它要訪問的表結構,以及上面的索引,還要分析表格裏的數據分佈,最後推斷出一個認爲比較優化的執行計劃。這個過程主要是在作各類計算,因此說是使用CPU比較集中的地方。對象
重編譯:不少時候,因爲數據量發生了變化,或者表結構變化。一樣的一句話,還要再次把執行計劃再作一遍,這個過程就是重編譯
看計數器 SQl Recompilations 對Batch Request /Sec 的比率和Sql Compilations 對 Batch Request /Sec 的比率。這個比率表示每秒請求的批處理中有多少個請求須要編譯或者重編譯。
通常建議重編譯比率 不超過1%。 編譯比率 不超過10%。
若是說這個比率比較高,須要跟蹤一下。
–SP: Recompile –RPC: Completed –Auto Stats 引發重編譯和編譯的緣由,可能有如下狀況
1)set 語句的變化
2)統計信息發生變化
3)不明確的對象名稱 --使用明確的對象名稱
4)HINT提示 --去掉 WITH RECOMPILE
排序和聚合運算
在查詢的時候,常常會作order by,distinct這樣的操做,也會作avg,min,max,sum這樣的聚合計算。在數據已經被加載到內存後,就要使用cpu把這些計算作完。因此這也是耗費cpu的地方。
表格join操做
當語句須要兩張表作鏈接的時候,sql server經常會選擇Nested Loop 或者hash算法。算法的完成要運行cpu。尤爲是當sql server選擇了錯誤的鏈接算法的時候。
低效的執行計劃
1)過期的統計信息
2)缺失索引
3)錯誤的索引
4)代碼質量
並行查詢
若是查詢的開銷 > 並行的開銷閾值 (默認爲5 秒), 查詢將會並行執行 在大多數狀況下,並行可以增強查詢的性能然而,一個給定查詢的響應時間必須從整個系統的吞吐量和系統 上的其餘查詢出發來綜合考慮。
好比說一條指令要讀入100萬條記錄。若是一個線程作,可能須要10秒,若是10個線程作,每一個線程讀10萬條記錄,可能每一個線程只須要1秒,就算加上線程間同步時間,可能總共2秒就完成了。縮短了查詢的時間。可是在這2秒裏,有10個cpu須要全力運行這10個線程,別的用戶發過來的指令會受到影響,甚至可能會拿不到cpu執行。
對於併發度要求比較高,每一個用戶都要求有及時響應的OLTP系統,通常會建議設置每一個指令都只用一個線程執行,從而保證SQL SERVER在任何一個時間點,都有多個CPU能夠響應多個請求。即把 Max Degree of Parallelism 設成1.
對於併發用戶比較少的,常常會有複雜查詢的系統,能夠把Max Degree of Parallelism的值設成cpu的數量值。若是也要考慮併發,能夠設成小一點。
若是說當前系統cpu比較高,也能夠經過動態管理視圖來查詢:
select
highest_cpu_queries.*,q.dbid,
q.objectid, q.number, q.encrypted, q.[text]
from
(select top 50 qs.*
from sys.dm_exec_query_stats qs
order by qs.total_worker_time desc) as highest_cpu_queries
cross apply sys.dm_exec_sql_text(plan_handle) as q
order by highest_cpu_queries.total_worker_time desc
go
或者找最常常作重編譯的存儲過程
select top 25 sql_text.text, sql_handle, plan_generation_num, execution_count,
dbid, objectid
from sys.dm_exec_query_stats a
cross apply sys.dm_exec_sql_text(sql_handle) as sql_text
where plan_generation_num >1
order by plan_generation_num desc
go