SQL數據庫管理系統的優化方案(表的主鍵、外鍵、索引設計)

    在基本表設計中,表的主鍵、外鍵、索引設計佔有非常重要的地位,但系統設計人員往往只注重於滿足用戶要求,而沒有從系統優化的高度來認識和重視它們。實際上,它們與系統的運行性能密切相關。現在從系統數據庫優化角度討論這些基本概念及其重要意義: 

(1)主鍵(Primary Key):主鍵被用於複雜的SQL語句時,頻繁地在數據訪問中被用到。一個表只有一個主鍵。主鍵應該有固定值(不能爲Null或缺省值,要有相對穩定性),不含代碼信息,易訪問。把常用(衆所周知)的列作爲主鍵纔有意義。短主鍵最佳(小於25bytes),主鍵的長短影響索引的大小,索引的大小影響索引頁的大小,從而影響磁盤I/O。主鍵分爲自然主鍵和人爲主鍵。自然主鍵由實體的屬性構成,自然主鍵可以是複合性的,在形成複合主鍵時,主鍵列不能太多,複合主鍵使得Join*作複雜化、也增加了外鍵表的大小。人爲主鍵是,在沒有合適的自然屬性鍵、或自然屬性複雜或靈敏度高時,人爲形成的。人爲主鍵一般是整型值(滿足最小化要求),沒有實際意義,也略微增加了表的大小;但減少了把它作爲外鍵的表的大小。 
(2)外鍵(Foreign Key):外鍵的作用是建立關係型數據庫中表之間的關係(參照完整性),主鍵只能從獨立的實體遷移到非獨立的實體,成爲後者的一個屬性,被稱爲外鍵。 
(3)索引(Index):利用索引優化系統性能是顯而易見的,對所有常用於查詢中的Where子句的列和所有用於排序的列創建索引,可以避免整表掃描或訪問,在不改變表的物理結構的情況下,直接訪問特定的數據列,這樣減少數據存取時間;利用索引可以優化或排除耗時的分類*作;把數據分散到不同的頁面上,就分散了插入的數據;主鍵自動建立了唯一索引,因此唯一索引也能確保數據的唯一性(即實體完整性);索引碼越小,定位就越直接;新建的索引效能最好,因此定期更新索引非常必要。索引也有代價:有空間開銷,建立它也要花費時間,在進行Insert、Delete和Update*作時,也有維護代價。索引有兩種:聚族索引和非聚族索引。一個表只能有一個聚族索引,可有多個非聚族索引。使用聚族索引查詢數據要比使用非聚族索引快。在建索引前,應利用數據庫系統函數估算索引的大小。 
① 聚族索引(Clustered Index):聚族索引的數據頁按物理有序儲存,佔用空間小。選擇策略是,被用於Where子句的列:包括範圍查詢、模糊查詢或高度重複的列(連續磁盤掃描);被用於連接Join*作的列;被用於Order by和Group by子句的列。聚族索引不利於插入*作,另外沒有必要用主鍵建聚族索引。 
② 非聚族索引(Nonclustered Index):與聚族索引相比,佔用空間大,而且效率低。選擇策略是,被用於Where子句的列:包括範圍查詢、模糊查詢(在沒有聚族索引時)、主鍵或外鍵列、點(指針類)或小範圍(返回的結果域小於整表數據的20%)查詢;被用於連接Join*作的列、主鍵列(範圍查詢);被用於Order by和Group by子句的列;需要被覆蓋的列。對只讀表建多個非聚族索引有利。索引也有其弊端,一是創建索引要耗費時間,二是索引要佔有大量磁盤空間,三是增加了維護代價(在修改帶索引的數據列時索引會減緩修改速度)。那麼,在哪種情況下不建索引呢?對於小表(數據小於5頁)、小到中表(不直接訪問單行數據或結果集不用排序)、單值域(返回值密集)、索引列值太長(大於20bitys)、容易變化的列、高度重複的列、Null值列,對沒有被用於Where子語句和Join查詢的列都不能建索引。另外,對主要用於數據錄入的,儘可能少建索引。當然,也要防止建立無效索引,當Where語句中多於5個條件時,維護索引的開銷大於索引的效益,這時,建立臨時表存儲有關數據更有效。 
批量導入數據時的注意事項:在實際應用中,大批量的計算(如電信話單計費)用C語言程序做,這種基於主外鍵關係數據計算而得的批量數據(文本文件),可利用系統的自身功能函數(如Sybase的BCP命令)快速批量導入,在導入數據庫表時,可先刪除相應庫表的索引,這有利於加快導入速度,減少導入時間。在導入後再重建索引以便優化查詢。 
(4)鎖:鎖是並行處理的重要機制,能保持數據併發的一致性,即按事務進行處理;系統利用鎖,保證數據完整性。因此,我們避免不了死鎖,但在設計時可以充分考慮如何避免長事務,減少排它鎖時間,減少在事務中與用戶的交互,杜絕讓用戶控制事務的長短;要避免批量數據同時執行,尤其是耗時並用到相同的數據表。鎖的徵用:一個表同時只能有一個排它鎖,一個用戶用時,其它用戶在等待。若用戶數增加,則Server的性能下降,出現“假死”現象。如何避免死鎖呢?從頁級鎖到行級鎖,減少了鎖徵用;給小表增加無效記錄,從頁級鎖到行級鎖沒有影響,若在同一頁內競爭有影響,可選擇合適的聚族索引把數據分配到不同的頁面;創建冗餘表;保持事務簡短;同一批處理應該沒有網絡交互。 
(5)查詢優化規則:在訪問數據庫表的數據(Access Data)時,要儘可能避免排序(Sort)、連接(Join)和相關子查詢*作。經驗告訴我們,在優化查詢時,必須做到: 
① 儘可能少的行; 
② 避免排序或爲儘可能少的行排序,若要做大量數據排序,最好將相關數據放在臨時表中*作;用簡單的鍵(列)排序,如整型或短字符串排序; 
③ 避免表內的相關子查詢; 
④ 避免在Where子句中使用複雜的表達式或非起始的子字符串、用長字符串連接; 
⑤ 在Where子句中多使用“與”(And)連接,少使用“或”(Or)連接; 
⑥ 利用臨時數據庫。在查詢多表、有多個連接、查詢複雜、數據要過濾時,可以建臨時表(索引)以減少I/O。但缺點是增加了空間開銷。 
除非每個列都有索引支持,否則在有連接的查詢時分別找出兩個動態索引,放在工作表中重新排序。

發佈了12 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章