本文主要講怎樣提高數(shù)據(jù)庫(kù)性能。
數(shù)據(jù)庫(kù)性能問(wèn)題的三個(gè)常見(jiàn)來(lái)源以及如何解決這些問(wèn)題的建議。
避免死鎖
死鎖Deadlock,意思是當(dāng)兩個(gè)進(jìn)程競(jìng)爭(zhēng)性的對(duì)同一資源的獨(dú)占訪問(wèn),但一次只能有一個(gè)進(jìn)程使用資源,從而數(shù)據(jù)庫(kù)性能會(huì)降低,變得緩慢。
死鎖有兩種類型:循環(huán)鎖Cyclelocks和轉(zhuǎn)換鎖Conversionlocks。
循環(huán)鎖
進(jìn)程要把一個(gè)被另一個(gè)進(jìn)程鎖定的資源轉(zhuǎn)換獨(dú)占鎖時(shí),就會(huì)發(fā)生循環(huán)鎖。
轉(zhuǎn)換鎖
當(dāng)一個(gè)線程試圖將一個(gè)鎖從一種獨(dú)占類型轉(zhuǎn)換為另一種獨(dú)占類型,但同時(shí)由于另一個(gè)線程已經(jīng)在該資源上持有共享鎖,會(huì)導(dǎo)致轉(zhuǎn)換鎖。
轉(zhuǎn)換鎖有三種形式:
Shared with Intent Exclusive (SIX):當(dāng)持有共享鎖的事務(wù)在某些頁(yè)或行上也有獨(dú)占鎖時(shí)發(fā)生。
Shared with intent update (SIU):當(dāng)持有共享鎖的事務(wù)也有一些頁(yè)或行被更新鎖鎖定時(shí)發(fā)生。
Update with Intent Exclusive (UIX):當(dāng)持有更新鎖的事務(wù)在某些頁(yè)或行上也有獨(dú)占鎖時(shí)發(fā)生。
修復(fù)死鎖的最佳方法是終止其中一個(gè)進(jìn)程并釋放鎖定的資源。 為了防止死鎖發(fā)生,預(yù)防措施如下:
創(chuàng)建更好的索引
調(diào)整事務(wù)優(yōu)先級(jí)
持有鎖的時(shí)間盡可能短
在獲得所需的所有信息之前不要提交事務(wù)
索引的碎片整理
隨著時(shí)間的推移,多次插入和刪除會(huì)導(dǎo)致索引碎片化。這種碎片可能是內(nèi)部的(由具有太多可用空間的頁(yè)面引起)或外部的(當(dāng)頁(yè)面的邏輯順序錯(cuò)誤時(shí)發(fā)生)。
無(wú)論哪種類型,引發(fā)的一個(gè)癥狀是數(shù)據(jù)庫(kù)的查詢非常緩慢。
可以使用sys.dm_db_index_physical_stats診斷索引碎片:檢測(cè)特定索引、表或索引視圖上的所有索引、數(shù)據(jù)庫(kù)中的所有索引或所有數(shù)據(jù)庫(kù)中的所有索引中的碎片。
除非索引永遠(yuǎn)不會(huì)更改,否則無(wú)法防止某種程度的索引碎片。但是通過(guò)一些注意事項(xiàng)可以最大限度地減少碎片對(duì)數(shù)據(jù)庫(kù)性能的影響:
要:注意可能導(dǎo)致頁(yè)面拆分的功能
要:實(shí)施適當(dāng)?shù)乃饕畛湟蜃?/p>
不要:更新記錄以使其更長(zhǎng)
不要:插入具有隨機(jī)鍵值的記錄
在修復(fù)索引碎片性能問(wèn)題的第一步是確定問(wèn)題有多大。運(yùn)行sys.dm_db_index_physical_stats以分析碎片級(jí)別。然后決定是否重建索引、重組索引還是什么都不做。
重建:碎片超過(guò)30%時(shí)重建索引
重組:重組具有11-30%碎片的索引
忽略:10%或更少的碎片級(jí)別不會(huì)造成性能問(wèn)題,因此無(wú)需執(zhí)行任何操作
優(yōu)化查詢語(yǔ)句(QUERY)
數(shù)據(jù)庫(kù)運(yùn)行緩慢的其中一個(gè)原因是有我們寫的QUERY造成的,所以需要優(yōu)化查詢語(yǔ)句。
無(wú)論是追溯調(diào)整查詢語(yǔ)句以獲得更好的數(shù)據(jù)庫(kù)性能,還是從一開(kāi)始就主動(dòng)將其納入,好的習(xí)慣將有助于確保查詢快速準(zhǔn)確地返回:
確定業(yè)務(wù)需求
避免 select? *
使用INNERJOIN子句而不是WHERE子句創(chuàng)建連接
使用WHERE定義過(guò)濾器
避免使用前導(dǎo) % 通配符
使用存儲(chǔ)過(guò)程
批量進(jìn)行刪除和更新