影響資料庫(kù)效能的重要因素不外乎以下四個(gè): 1. 資料庫(kù)的邏輯設(shè)計(jì) 2. 資料庫(kù)的實(shí)體設(shè)計(jì) 3. 伺服器的硬體規(guī)格 4. 索引規(guī)劃與SQL敘述
在資料庫(kù)邏輯設(shè)計(jì)方面 首先需要考慮資料庫(kù)主要是用於儲(chǔ)存交易資料還是分析資料(OLAP)?如果是交易資料庫(kù),則儘可能做到第三正規(guī)化,以減少重覆的資料,節(jié)省儲(chǔ)存的空間。當(dāng)資料列變少時(shí),有助於資料的排序與索引,但無(wú)可避免的,資料表數(shù)目與關(guān)聯(lián)反而會(huì)變多,增加查詢的複雜度。如果只是分析資料庫(kù),對(duì)正規(guī)化的要求,反而就沒(méi)有必要了。
在資料庫(kù)實(shí)體設(shè)計(jì)方面 特別是一些大型的資料表,可以考慮垂直或水平的分割,並分別放在不同的磁碟中,以提高查詢的效能。另外將資料與索引分開(kāi)存放,也是達(dá)到相同的效果。
在伺服器的硬體規(guī)格方面 如果在預(yù)算許可的情況下,硬體升級(jí)也是不錯(cuò)的方案。硬體升級(jí)可分為垂直延展(scale up)與水平延展(scale out)兩種,其中垂直延展是指更換更高級(jí)的CPU或更高轉(zhuǎn)速的硬碟、增加CPU或RAM數(shù)量等。水平延展則是指使用多部伺服器建立伺服器叢集,增加處理容量,提高效能。
在索引規(guī)劃與SQL敘述方面 良好的索引規(guī)劃是資料庫(kù)效能的基礎(chǔ)。簡(jiǎn)單來(lái)說(shuō),索引就像一本書(shū)的目錄,透過(guò)目錄可以快速找到所需的內(nèi)容,建立索引也是相同的道理。索引可以分成叢集索引與非叢集索引。一個(gè)資料表只能有一個(gè)叢集索引,但可以有多個(gè)非叢集索引。叢集索引與叢集索引的主要差別在於叢集索引的順序與資料實(shí)體儲(chǔ)存的順序有關(guān),而非叢集索引則與資料實(shí)體儲(chǔ)存沒(méi)有直接的關(guān)係。
SQL敘述是管理與存取資料庫(kù)的唯一途徑,執(zhí)行時(shí)往往會(huì)耗用70%以上的系統(tǒng)資源,由此可見(jiàn)SQL敘述對(duì)資料庫(kù)效能的重要性。SQL敘述的特色是易學(xué)易懂,但難於精通。相同的結(jié)果,可以有不同的寫(xiě)法,因此如何撰寫(xiě)良好效能的SQL敘述是資料庫(kù)開(kāi)發(fā)人員的一大挑戰(zhàn)。
本文將重點(diǎn)放在第四個(gè)部份。如何建立適合的索引與選擇索引類型。另外也簡(jiǎn)單說(shuō)明了撰寫(xiě)SQL敘述時(shí)的注意事項(xiàng)與哪些替代的寫(xiě)法?
在正式進(jìn)入主題之前,先對(duì)效能的評(píng)估有個(gè)基本的認(rèn)識(shí)。通常我們可以從下面兩個(gè)方面來(lái)評(píng)估效能是否需要改善,以及改善的程度。首先可以檢查邏輯讀取(logic reads)(註1)的次數(shù)。讀取的次數(shù)越小,表示查詢效能越佳,反之則越差。另外也可以檢查執(zhí)行計(jì)畫(huà),如果有使用了table scan或出現(xiàn)紅字,則表示尚有改善的空間,儘可能做到index seek。
索引規(guī)劃 哪些欄位適合建立索引?又有哪些不適合建立索引?一般而言,經(jīng)常用於連結(jié)條件、查詢,以及排序或資料密度較高的欄位均適合建立索引。一些很少查詢、資料重複性太高的資料(例如性別),以及text與image等大型的資料均不適合建立索引。
良好的SQL敘述 SQL敘述的執(zhí)行效能,可以從下面幾個(gè)方面來(lái)改善: 1. and與or的使用 and,可用於取代between。只有單一條件有索引,就會(huì)使用索引。條件越多,選擇性越多,速度也越快。 or,可用於取代in。當(dāng)所有條件均有索引時(shí),才會(huì)使用索引。例如找出姓林,名叫彼得的員工 select * from employee where lastname= '林' or firstname= '彼得' 如果只有在lastname欄位建立索引,也不會(huì)使用索引來(lái)查詢。 改善的作法是將SQL敘述分解成多個(gè)單一條件的SQL敘述,然後使用union將結(jié)果聯(lián)集來(lái)。 select * from employee where lastname= '林' union select * from employee where firstname= '彼得' 另外也可以在lastname和firstname建立複合索引,提高索引覆蓋率。
2. where子句僅可能不使用運(yùn)算式
3. 僅可能少用like進(jìn)行模糊查詢,特別是對(duì)於一些大型的資料表。
4. 僅可能使用stored procedure
事實(shí)上過(guò)多或不適當(dāng)?shù)乃饕赡苡绊懖樵兣c更新的速度,因此不建議自行建立索引。只要資料庫(kù)的邏輯設(shè)計(jì)是合理的,使用SQL Server提供的索引微調(diào)器便可以幫助您方便而有效地來(lái)建立索引。
註1:邏輯讀取的次數(shù)是指當(dāng)執(zhí)行SQL敘述時(shí),讀取資料頁(yè)(page)的次數(shù)。為了檢查邏輯讀取的次數(shù),請(qǐng)執(zhí)行Set statistics IO ON開(kāi)啟讀寫(xiě)統(tǒng)計(jì)。
|