SQL性能殺手
在已經(jīng)優(yōu)化了硬件烦绳、操作系統(tǒng)和SQL配置的情況下毁涉,SQL中的性能殺手:
·低質(zhì)量的索引
·不精確的統(tǒng)計(jì)
·過(guò)多的阻塞和死鎖
·低質(zhì)量的查詢?cè)O(shè)計(jì)
·低質(zhì)量的數(shù)據(jù)庫(kù)設(shè)計(jì)
·過(guò)多的碎片
·不可重用的執(zhí)行
·低質(zhì)量的執(zhí)行計(jì)劃
·執(zhí)行計(jì)劃頻繁重編譯
·游標(biāo)的錯(cuò)誤使用
·數(shù)據(jù)庫(kù)日志的錯(cuò)誤配置
·過(guò)多使用或者錯(cuò)誤配置tempdb
低質(zhì)量的索引
對(duì)于一個(gè)缺乏正確索引的查詢联贩,SQL必須在執(zhí)行查詢時(shí)讀取和處理多得多的數(shù)據(jù)歹茶,這導(dǎo)致磁盤(pán)先匪、內(nèi)存和CPU上有很大的壓力种吸,顯著的增加查詢執(zhí)行時(shí)間。增加查詢執(zhí)行時(shí)間導(dǎo)致過(guò)多的阻塞和死鎖呀非。
不精確的統(tǒng)計(jì)
SQL服務(wù)器非常依賴基于開(kāi)銷(xiāo)的優(yōu)化坚俗,所以精確的數(shù)據(jù)分布統(tǒng)計(jì)對(duì)于有效的索引使用極端重要镜盯。沒(méi)有精準(zhǔn)的統(tǒng)計(jì),SQL內(nèi)建的查詢優(yōu)化器就不能精確的估計(jì)查詢影響的行數(shù)猖败。
性能監(jiān)測(cè)工具
運(yùn)行perfmon
查詢每秒登錄的時(shí)間
Select cntr_value
From sys.dm_os_performance_counters
Where OBJECT_NAM = ‘’//服務(wù)器名稱(chēng)
And counter_name = ‘logins/sec’//每秒登錄多少次
識(shí)別發(fā)生在系統(tǒng)中的等待速缆,查詢當(dāng)前最長(zhǎng)的等待
Select top 10 * from sys.dm_os_wait_stats
Order by wait_time_ms desc
當(dāng)SQL耗盡了緩沖或內(nèi)存時(shí),SQL中的一個(gè)進(jìn)程(lazy writer)必須不段的工作恩闻,這將消費(fèi)額外的CPU周期并且執(zhí)行附加的物理磁盤(pán)I/O將內(nèi)存頁(yè)面寫(xiě)回磁盤(pán)
通過(guò)下面語(yǔ)句管理最小最大內(nèi)存配置艺糜。
Exec sp_configure ‘min server memory(MB)’
Exec sp_configure ‘max server memory(MB)’
注意:服務(wù)器最小內(nèi)存默認(rèn)值為0,最大為2147483647幢尚,服務(wù)器最大內(nèi)存不能設(shè)置為小于4MB破停。
查詢?cè)O(shè)計(jì)分析
·查詢?cè)O(shè)計(jì)影響性能的方面
·查詢?cè)O(shè)計(jì)有效使用索引的方法
·優(yōu)化器提示在查詢性能上的作用
·數(shù)據(jù)庫(kù)約束在查詢性能上的作用
·資源密集度較低的查詢?cè)O(shè)計(jì)
·有效使用過(guò)程緩沖的查詢?cè)O(shè)計(jì)
·減少網(wǎng)絡(luò)開(kāi)銷(xiāo)的查詢?cè)O(shè)計(jì)
·減少查詢事務(wù)開(kāi)銷(xiāo)的技術(shù)
一般記住以下建議能確保最佳性能:
·在小的結(jié)果集上操作
·有效使用索引
·避免優(yōu)化器提示
·使用域和參照完整性
·避免資源密集型的查詢
·減少網(wǎng)絡(luò)傳輸數(shù)量
·減少事務(wù)開(kāi)銷(xiāo)
在小的結(jié)果集上操作
應(yīng)該限制操作的數(shù)據(jù)量,包括列數(shù)和行數(shù)尉剩。遵循原則:
·限制選擇列表中的列數(shù)
·使用高選擇性的WHERE子句來(lái)限制返回的行數(shù)
限制選擇列表中的列數(shù)
不要使用輸出結(jié)果不需要的列真慢。例如select *,錯(cuò)誤
Select [Name],TerritoryID from SalesTerritory as st
Where st.[Name] = ‘a(chǎn)ustralia’
在NAME列上的覆蓋索引使通過(guò)索引本身的查詢很快理茎,而不需要訪問(wèn)聚集索引黑界。當(dāng)開(kāi)啟STATISTICS IO和STATISTICS TIME開(kāi)關(guān),將得到以下邏輯讀取數(shù)量和執(zhí)行時(shí)間
Table ‘SalesTerritory’.Scan count 0, logical reads 2,CPU time = 0ms,elapsed time = 17ms
使用高選擇性的WHERE子句
在WHERE子句中引用的列的選擇性控制著列上索引的使用皂林。
11.3有效的使用索引
索引使用的查詢?cè)O(shè)計(jì)原則:
·避免不可參數(shù)化的搜索
·避免在WHERE子句列上使用算數(shù)運(yùn)算符
·避免WHERE子句列上的函數(shù)
11.3.1避免不可參數(shù)化的搜索
11.3.2避免WHERE子句列上的算術(shù)運(yùn)算符
如:
SELECT * FROM TABLE AS POH
WHERE POH.ID * 2 = 3400
改為
SELECT * FROM TABLE AS POH
WHERE POH.ID = 3400/2
11.3.3避免WHERE子句列上的函數(shù)
如:
SELECT D.NAME FROM TABLE AS D WHERE SUBSTRING(D.[NAME],1,1) = ‘F’
改為:
SELECT D.NAME FROM TABLE AS D WHERE D.[NAME] LIKE ‘F%’
11.4避免優(yōu)化器提示
11.5使用域和參照完整性
11.5.1非空約束
非空約束用于定義特定列中不能輸入NULL值從而實(shí)現(xiàn)域完整性园爷。
對(duì)比沒(méi)有NULL和有NULL的執(zhí)行過(guò)程
沒(méi)有NULL的
有NULL的,僅僅只是在后面增加了式撼,or p.firstname is null
注意:當(dāng)數(shù)據(jù)為知時(shí)童社,也許不能設(shè)定默認(rèn)值。這時(shí)候又將出現(xiàn)NULL著隆。這是不可避免的扰楼,但是要盡可能的減少這樣的情況。
當(dāng)不可避免的要處理NULL值時(shí)美浦,可以使用過(guò)濾索引來(lái)從索引中刪除NULL的值弦赖,從而改進(jìn)索引的性能。
11.5.2聲明參照完整性
聲明參照完整性用于定義父表和子表上的參照完整性浦辨。它確保子表中的記錄只當(dāng)父表中存在對(duì)應(yīng)記錄時(shí)存在蹬竖。這個(gè)原則唯一例外的是,鏈接子表和附表行的子表標(biāo)識(shí)符可以為NULL值流酬。
11.6避免資源密集型查詢
減少查詢覆蓋的技術(shù)有:
·避免數(shù)據(jù)類(lèi)型轉(zhuǎn)換
·使用EXISTS代替COUNT(*)來(lái)驗(yàn)證數(shù)據(jù)存在
·使用UNION ALL代替UNION
·為聚合和排序操作使用索引
·避免批查詢中的局部變量
·小心命名存儲(chǔ)過(guò)程
(2013-3-25)