在應用系統中,尤其在聯機事務處理系統中,對資料查詢及處理速度已成為衡量應用系統成敗的標準。而採用索引來加快資料處理速度也成為廣大資料庫使用者所接受的優化方法。
在良好的資料庫設計基礎上,能有效地使用索引是sql server取得高效能的基礎,sql server採用基於代價的優化模型,它對每乙個提交的有關表的查詢,決定是否使用索引或用哪乙個索引。因為查詢執行的大部分開銷是磁碟i/o,使用索引 提高效能的乙個主要目標是避免全表掃瞄,因為全表掃瞄需要從磁碟上讀表的每乙個資料頁,如果有索引指向資料值,則查詢只需讀幾次磁碟就可以了。所以如果建 立了合理的索引,優化器就能利用索引加速資料的查詢過程。但是,索引並不總是提高系統的效能,在增、刪、改操作中索引的存在會增加一定的工作量,因此,在 適當的地方增加適當的索引並從不合理的地方刪除次優的索引,將有助於優化那些效能較差的sql server應用。實踐表明,合理的索引設計是建立在對各種查詢的分析和**上的,只有正確地使索引與程式結合起來,才能產生最佳的優化方案。本文就 sql server索引的效能問題進行了一些分析和實踐。
一、聚簇索引(clustered indexes)的使用
聚簇索引是一種對磁碟上實際資料重新組織以按指定的乙個或多個列的值排序。由於聚簇索引的索引頁面指標指向資料頁面,所以使用聚簇索引查詢資料幾乎 總是比使用非聚簇索引快。每張表只能建乙個聚簇索引,並且建聚簇索引需要至少相當該錶120%的附加空間,以存放該錶的副本和索引中間頁。建立聚簇索引的 思想是:
1、大多數表都應該有聚簇索引或使用分割槽來降低對錶尾頁的競爭,在乙個高事務的環境中,對最後一頁的封鎖嚴重影響系統的吞吐量。
2、在聚簇索引下,資料在物理上按順序排在資料頁上,重複值也排在一起,因而在那些包含範圍檢查(between、<、<=、& gt;、>=)或使用group by或order by的查詢時,一旦找到具有範圍中第乙個鍵值的行,具有後續索引值的行保證物理上毗連在一起而不必進一步搜尋,避免了大範圍掃瞄,可以大大提高查詢速度。
3、在乙個頻繁發生插入操作的表上建立聚簇索引時,不要建在具有單調上公升值的列(如identity)上,否則會經常引起封鎖衝突。
4、在聚簇索引中不要包含經常修改的列,因為碼值修改後,資料行必須移動到新的位置。
5、選擇聚簇索引應基於where子句和連線操作的型別。
聚簇索引的侯選列是:
1、主鍵列,該列在where子句中使用並且插入是隨機的。
2、按範圍訪問的列,如pri_order > 100 and pri_order < 200。
3、在group by或order by中使用的列。
4、不經常修改的列。
5、在連線操作中使用的列。
二、非聚簇索引(nonclustered indexes)的使用
sql server預設情況下建立的索引是非聚簇索引,由於非聚簇索引不重新組織表中的資料,而是對每一行儲存索引列值並用乙個指標指向資料所在的頁面。換句話 說非聚簇索引具有在索引結構和資料本身之間的乙個額外級。乙個表如果沒有聚簇索引時,可有250個非聚簇索引。每個非聚簇索引提供訪問資料的不同排序順 序。在建立非聚簇索引時,要權衡索引對查詢速度的加快與降低修改速度之間的利弊。另外,還要考慮這些問題:
1、索引需要使用多少空間。
2、合適的列是否穩定。
3、索引鍵是如何選擇的,掃瞄效果是否更佳。
4、是否有許多重複值。
對更新頻繁的表來說,表上的非聚簇索引比聚簇索引和根本沒有索引需要更多的額外開銷。對移到新頁的每一行而言,指向該資料的每個非聚簇索引的頁級行 也必須更新,有時可能還需要索引頁的分理。從乙個頁面刪除資料的程序也會有類似的開銷,另外,刪除程序還必須把資料移到頁面上部,以保證資料的連續性。所 以,建立非聚簇索引要非常慎重。非聚簇索引常被用在以下情況:
1、某列常用於集合函式(如sum,....)。
2、某列常用於join,order by,group by。
3、查尋出的資料不超過表中資料量的20%。
三、覆蓋索引(covering indexes)的使用
覆蓋索引是指那些索引項中包含查尋所需要的全部資訊的非聚簇索引,這種索引之所以比較快也正是因為索引頁中包含了查尋所必須的資料,不需去訪問資料頁。如果非聚簇索引中包含結果資料,那麼它的查詢速度將快於聚簇索引。
但是由於覆蓋索引的索引項比較多,要占用比較大的空間。而且update操作會引起索引值改變。所以如果潛在的覆蓋查詢並不常用或不太關鍵,則覆蓋索引的增加反而會降低效能。
四、索引的選擇技術
p_detail是住房公積金管理系統中記錄個人明細的表,有890000行,觀察在不同索引下的查詢執行效果,測試在c/s環境下進行,客戶機是 ibm pii350(記憶體64m),伺服器是dec alpha1000a(記憶體128m),資料庫為sybase11.0.3。
1、select count(*) from p_detail whereop_date>』19990101』 and op_date<』
19991231』 and pri_surplus1>300
2、select count(*),sum(pri_surplus1) from p_detail
where op_date>』19990101』 and
pay_month between『199908』 and』199912』
不建任何索引查詢1 1分15秒
查詢2 1分7秒
在op_date上建非聚簇索引查詢1 57秒
查詢2 57秒
在op_date上建聚簇索引查詢1 <1秒
查詢2 52秒
在pay_month、op_date、pri_surplus1上建索引查詢1 34秒
查詢2 <1秒
在op_date、pay_month、pri_surplus1上建索引查詢1 <1秒
查詢2 <1秒
從以上查詢效果分析,索引的有無,建立方式的不同將會導致不同的查詢效果,選擇什麼樣的索引基於使用者對資料的查詢條件,這些條件體現於where從句和join表示式中。一般來說建立索引的思路是:
(1)主鍵時常作為where子句的條件,應在表的主鍵列上建立聚簇索引,尤其當經常用它作為連線的時候。
(2)有大量重複值且經常有範圍查詢和排序、分組發生的列,或者非常頻繁地被訪問的列,可考慮建立聚簇索引。
(3)經常同時訪問多列,且每列都含有重複值可考慮建立復合索引來覆蓋乙個或一組查詢,並把查詢引用最頻繁的列作為前導列,如果可能盡量使關鍵查詢形成覆蓋查詢。
(4)如果知道索引鍵的所有值都是唯一的,那麼確保把索引定義成唯一索引。
(5)在乙個經常做插入操作的表上建索引時,使用fillfactor(填充因子)來減少頁**,同時提高併發度降低死鎖的發生。如果在唯讀表上建索引,則可以把fillfactor置為100。
(6)在選擇索引鍵時,設法選擇那些採用小資料型別的列作為鍵以使每個索引頁能夠容納盡可能多的索引鍵和指標,通過這種方式,可使乙個查詢必須遍歷的索引頁面降到最小。此外,盡可能地使用整數為鍵值,因為它能夠提供比任何資料型別都快的訪問速度。
五、索引的維護
上面講到,某些不合適的索引影響到sql server的效能,隨著應用系統的執行,資料不斷地發生變化,當資料變化達到某乙個程度時將會影響到索引的使用。這時需要使用者自己來維護索引。索引的維護包括:
1、重建索引
隨著資料行的插入、刪除和資料頁的**,有些索引頁可能只包含幾頁資料,另外應用在執行大塊i/o的時候,重建非聚簇索引可以降低分片,維護大塊i/o的效率。重建索引實際上是重新組織b-樹空間。在下面情況下需要重建索引:
(1)資料和使用模式大幅度變化。
(2)排序的順序發生改變。
(3)要進行大量插入操作或已經完成。
(4)使用大塊i/o的查詢的磁碟讀次數比預料的要多。
(5)由於大量資料修改,使得資料頁和索引頁沒有充分使用而導致空間的使用超出估算。
(6)dbcc檢查出索引有問題。
當重建聚簇索引時,這張表的所有非聚簇索引將被重建。
2、索引統計資訊的更新
當在乙個包含資料的表上建立索引的時候,sql server會建立分布資料頁來存放有關索引的兩種統計資訊:分布表和密度表。優化器利用這個頁來判斷該索引對某個特定查詢是否有用。但這個統計資訊並不 動態地重新計算。這意味著,當表的資料改變之後,統計資訊有可能是過時的,從而影響優化器追求最有工作的目標。因此,在下面情況下應該執行update statistics命令:
(1)資料行的插入和刪除修改了資料的分布。
(2)對用truncate table刪除資料的表上增加資料行。
(3)修改索引列的值。
六、結束語
1、在查詢中很少或從不引用的列不會受益於索引,因為索引很少或從來不必搜尋基於這些列的行。
2、只有兩個或三個值的列,如男性和女性(是或否),從不會從索引中得到好處。
另外,鑑於索引加快了查詢速度,但減慢了資料更新速度的特點。可通過在乙個段上建表,而在另乙個段上建其非聚簇索引,而這兩段分別在單獨的物理裝置上來改善操作效能。
SQL Server 中建立索引
索引的概念 建立索引的目的 提高了資料庫系統的效能,加快資料的查詢速度與減少系統的響應時間。索引是什麼 資料庫中的索引類似於一本書的目錄,在一本書中通過目錄可以快速找到你想要的資訊,而不需要讀完全書。在資料庫中,資料庫程式使用索引可以快速查詢到表中的資料,而不必掃瞄整個表。書中的目錄是乙個字詞以及各...
SQL Server索引中的include列
從sql server 2005 開始,可以通過將include列新增到非聚集索引擴充套件其功能。create nonclustered index ind user id createtime on dbo workitems user id asc,createtime desc include...
SQLServer中設定XML索引
xml索引分為主xml索引和次xml索引 1.主xml索引 為了完整 一致的表示xml的值,格式 create primary xml index indexname on tablename columname 2.次xml索引 對於xpath和xquery表示式,可以使用xml次索引 path索...