數據庫索引的作用和優點缺點以及索引的11中用法


為什么要創建索引呢?這是因為,創建索引可以大大提高系統的性能。
第一,通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
第二,可以大大加快 數據的檢索速度,這也是創建索引的最主要的原因。
第三,可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
第四,在使用分組和排序 子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

也許會有人要問:增加索引有如此多的優點,為什么不對表中的每一個列創建一個索引呢?這種想法固然有其合理性,然而也有其片面性。雖然,索引有許多優點, 但是,為表中的每一個列都增加索引,是非常不明智的。這是因為,增加索引也有許多不利的一個方面。

第一,創建索引和維護索引要耗費時間,這種時間隨着數據 量的增加而增加。
第二,索引需要占物理空間,除了數據表占數據空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。
第三,當對表中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

索引是建立在數據庫表中的某些列的上面。因此,在創建索引的時候,應該仔細考慮在哪些列上可以創建索引,在哪些列上不能創建索引。一般來說,應該在這些列 上創建索引,例如:

在經常需要搜索的列上,可以加快搜索的速度;
在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;
在經常用在連接的列上,這 些列主要是一些外鍵,可以加快連接的速度;
在經常需要根據范圍進行搜索的列上創建索引,因為索引已經排序,其指定的范圍是連續的;
在經常需要排序的列上創 建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;
在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

同樣,對於有些列不應該創建索引。一般來說,不應該創建索引的的這些列具有下列特點:

第一,對於那些在查詢中很少使用或者參考的列不應該創建索引。這是因 為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。
第二,對於那 些只有很少數據值的列也不應該增加索引。這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行占了表中數據行的很大比 例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。
第三,對於那些定義為text, image和bit數據類型的列不應該增加索引。這是因為,這些列的數據量要么相當大,要么取值很少。
第四,當修改性能遠遠大於檢索性能時,不應該創建索 引。這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因 此,當修改性能遠遠大於檢索性能時,不應該創建索引。

創建索引的方法和索引的特征
創建索引的方法
創建索引有多種方法,這些方法包括直接創建索引的方法和間接創建索引的方法。直接創建索引,例如使用CREATE INDEX語句或者使用創建索引向導,間接創建索引,例如在表中定義主鍵約束或者唯一性鍵約束時,同時也創建了索引。雖然,這兩種方法都可以創建索引,但 是,它們創建索引的具體內容是有區別的。
使用CREATE INDEX語句或者使用創建索引向導來創建索引,這是最基本的索引創建方式,並且這種方法最具有柔性,可以定制創建出符合自己需要的索引。在使用這種方式 創建索引時,可以使用許多選項,例如指定數據頁的充滿度、進行排序、整理統計信息等,這樣可以優化索引。使用這種方法,可以指定索引的類型、唯一性和復合 性,也就是說,既可以創建聚簇索引,也可以創建非聚簇索引,既可以在一個列上創建索引,也可以在兩個或者兩個以上的列上創建索引。

通過定義主鍵約束或者唯一性鍵約束,也可以間接創建索引。主鍵約束是一種保持數據完整性的邏輯,它限制表中的記錄有相同的主鍵記錄。在創建主鍵約束 時,系 統自動創建了一個唯一性的聚簇索引。雖然,在邏輯上,主鍵約束是一種重要的結構,但是,在物理結構上,與主鍵約束相對應的結構是唯一性的聚簇索引。換句話 說,在物理實現上,不存在主鍵約束,而只存在唯一性的聚簇索引。同樣,在創建唯一性鍵約束時,也同時創建了索引,這種索引則是唯一性的非聚簇索引。因此, 當使用約束創建索引時,索引的類型和特征基本上都已經確定了,由用戶定制的余地比較小。

當在表上定義主鍵或者唯一性鍵約束時,如果表中已經有了使用CREATE INDEX語句創建的標准索引時,那么主鍵約束或者唯一性鍵約束創建的索引覆蓋以前創建的標准索引。也就是說,主鍵約束或者唯一性鍵約束創建的索引的優先 級高於使用CREATE INDEX語句創建的索引。

索引的特征
索引有兩個特征,即唯一性索引和復合索引。
唯一性索引保證在索引列中的全部數據是唯一的,不會包含冗余數據。如果表中已經有一個主鍵約束或者唯一性鍵約束,那么當創建表或者修改表時,SQL Server自動創建一個唯一性索引。然而,如果必須保證唯一性,那么應該創建主鍵約束或者唯一性鍵約束,而不是創建一個唯一性索引。當創建唯一性索引 時,應該認真考慮這些規則:當在表中創建主鍵約束或者唯一性鍵約束時,SQL Server自動創建一個唯一性索引;如果表中已經包含有數據,那么當創建索引時,SQL Server檢查表中已有數據的冗余性;每當使用插入語句插入數據或者使用修改語句修改數據時,SQL Server檢查數據的冗余性:如果有冗余值,那么SQL Server取消該語句的執行,並且返回一個錯誤消息;確保表中的每一行數據都有一個唯一值,這樣可以確保每一個實體都可以唯一確認;只能在可以保證實體 完整性的列上創建唯一性索引,例如,不能在人事表中的姓名列上創建唯一性索引,因為人們可以有相同的姓名。

復合索引就是一個索引創建在兩個列或者多個列上。在搜索時,當兩個或者多個列作為一個關鍵值時,最好在這些列上創建復合索引。當創建復合索引時,應 該考慮 這些規則:最多可以把16個列合並成一個單獨的復合索引,構成復合索引的列的總長度不能超過900字節,也就是說復合列的長度不能太長;在復合索引中,所 有的列必須來自同一個表中,不能跨表建立復合列;在復合索引中,列的排列順序是非常重要的,因此要認真排列列的順序,原則上,應該首先定義最唯一的列,例 如在(COL1,COL2)上的索引與在(COL2,COL1)上的索引是不相同的,因為兩個索引的列的順序不同;為了使查詢優化器使用復合索引,查詢語 句中的WHERE子句必須參考復合索引中第一個列;當表中有多個關鍵列時,復合索引是非常有用的;使用復合索引可以提高查詢性能,減少在一個表中所創建的 索引數量。

索引是個既穩定又開放的信息結構,它有十一種功能。

1 分解功能

把文獻中的資料單元(如篇名、機構、短語、概念、物名、地名、書名、人名、字詞、符號等)一一分解,這就是索引的分解功能。它是索引工作的起跑線和索引編纂的基礎,沒有對文獻內容的這種分解功能,就沒有索引。

過去有些反對索引的人說,索引是把古人的著書“凌遲碎割”。他們對索引法的反對,實出於對流傳已久的那種落后的皓首窮經的陋習的偏愛和對新的治學方 法的無知,洪業曾鄙視他們為卧於涸轍的鮒魚,以升斗之水濟命,而不知西江水之可羡。雖然如此,但他們所謂的索引是把古人著書“凌遲碎割”的形象說法,卻從 反面十分正確地道破了索引的分解功能。

分解功能是索引作用於文獻的特殊功能,是它和其他檢索工作不同之處。

2 梳理功能

每種文獻都包容着許多不同性質的資料單元,它們在文獻中基本呈無序的狀態。把這些無序狀態的資料單元按外表特征或內容性質進行各歸其類的整理,這就 是索引的梳理功能。章學誠早就發現了這種功能,他在給《族孫守一論史表》信中要求其在治二十四史年表時一並把廿二史列傳中的人名編成索引,兩者互為經緯, 這樣便可使考古之士,於紛如亂絲之資料中,忽得梳通櫛理。

梳理功能是索引分解的后繼。如果只有分解功能而沒有梳理的功能,那么分解功能就沒有價值。

梳理是對資料單元的初分。如是字序,只要按筆划或音序歸類即可;如是類序只要按大類歸納即可。就像小姑娘梳頭,先把長發梳順,而編什么辮子或梳什么發型則是下一步的要求了。

3 組合功能

把梳理后的資料單元按照分類的要求,嚴密地組織它們的類別層次以及類目下的專題和同類目下款目的序列關系;或按字序的要求,嚴密地把標目的結構正裝 或倒裝、考慮限定詞對標目的限定和修飾的級數、或考慮字序和類序相結合的可能。此外,不論是類序或字序都要考慮參照系統的建立方案,使相關款目形成網絡, 使用戶檢索的眼界得以拓寬。這些,都是索引的組合功能。

過去,國外的同行曾把聖經的頁邊索引以“串珠”命名;我國有人曾把本草的方劑編成索引,以“針線”命名,“串珠”和“針線”是索引組合功能很形象的描繪。它使文獻資料單元成為一串串的明珠,成為被針線貫穿起來的資料單元的珍品。

4 結網功能

對某個領域的文獻進行有計划的索引編纂,利用類型的結構從各種不同的角度和層次對這些文獻的內容進行縱橫交錯和多維的揭示和組合,使之形成一個檢索這些文獻中的各種不同性質的資料單元的網絡。這就是索引的結網功能。

由“主表”和“詞族索引”、“范疇索引”、“英漢對照索引”等所組成的《漢語主題詞表》是由幾種不同性質的索引構建的一個主題詞間的聯系、辨析主題 詞詞義和被標引的文獻主題概念是否精確的一個隱含的語義網絡,它對文獻中的資料單元產生族性檢索和擴大檢索途徑的作用。這個網絡的結構和作用就是運用索引 結網功能的一個范例。

《古今圖書集成》囊括了清初以前絕大部分的文獻,是我國現存最大的一部類書,廣西大學林仲湘等根據它的特點,分別編了經線索引、緯線索引、圖表索 引、人物傳記索引、職方典匯考引和禽蟲草木三典釋名索引,從該書的各級類目和內容等不同角度交叉編結了一個嚴密的揭示網絡,這又是索引結網功能的具體運用 的例證。

5 揭示功能

分解功能只是客觀地對文獻進行解剖,而揭示功能有較強的目的性,它最常出現的是按專業的需要挑選某些資料單元。

在主題索引的編制中,主題概念的分析和主題詞的選用,包括對隱性主題的析出是這種功能的體現。

各種專題索引或各種專業的文摘索引也是索引揭示功能的運用。清朝徐克祺稱贊蔡烈先的《本草萬方針線》為鏡考、為燭照,這是對索引揭示功能很生動的形容。

6 鑒別功能

文獻是作者思維的物化,包含了作者用以施展其聰明才智的特有的言語軌跡及其思想氣質。在文獻的出版史中,出於各種不同的動機和原因,真偽之作疊出, 為杜偽辨真,不少人引經據典,注疏考證,一字之微,動千萬言,甚至引發了校勘學的出現。近年來又產生了利用索引進行鑒別的方法,通過逐字索引分解被鑒別的 文獻,即同時從兩種版本中分析作者用字(詞)的規律和頻率以甄別其真偽。

英國的女研究學家凱洛萊因·斯彼琴曾對莎士比亞的劇作進行過有趣的用詞統計和分析,她發現,莎氏使用的許多詩意的語言都和大自然以及鄉村生活有關。 又有人在研究司馬遷的《史記·貨殖列傳》時,發現這篇不到5000字的文章竟使用49次“富”字,由此得出,致“富”是這篇論文的主題。這些事例證明通過 對文獻中用詞的解剖可以發現作者的特有氣質和語言習慣,索引可利用這種潛在的規律辨析文獻的真偽。

7 追蹤功能

索引像只嗅覺靈敏的警犬一樣能追蹤各種領域的事物在文獻中留下來的痕跡。

一部舊時代報紙的索引,能追蹤那個時代的重大歷史事件,並清晰地再現這些重大的歷史事件脈絡;一部類書的索引,能追蹤許多名人的各方面的成就和言行;一種專業期刊的刊后索引,能追蹤當年該專業學科研究的動態;一部跨多年度的報刊回溯索引,就是一部多功能的追蹤記錄。

追蹤,是索引的功能之一。

8 導航功能

導航就是指引,它帶有較強的評價取向,索引具有這種功能。

過去,我國有一些所謂新產品,在技術人員的積極努力下問市了,但到國際市場上卻被打回票,因為這種新產品在別的國家已成老產品。技術人員的情報鼻子不靈,其中原因之一是不查閱有關的索引,不依靠這個情報導航工具,以致迷失了生產的方向。

在哲學社會科學的領域中,索引經常能提供在某個時期某個專業的理論動向和水平的第一手材料,許多科研工作者就依靠索引的導航,找到自己出發的港灣和要達到的彼岸。

洪業在《引得說》中指出:“引得者,予學者以游翔於載籍之舟車也。舟車愈善,則其所游愈廣,所入愈深。”這就是索引的導航功能。

9 執簡功能

您感到在信息爆炸的文獻環境中很難伸展自己的科研手腳吧?那么,請您先為自己的研究對象編編索引,那就可以執簡御繁了。我國的史學家顧頡剛曾說: “我常想暫不辦學術研究所而先辦材料整理所。”“索引,也是研究的基礎的一種,它能給您一個鑰匙,使您在許多頭緒不清的材料中找出頭緒,而得到你所需要的 東西。”

國外盛行的那種快速反映科研情報的KWIC、KWOC,就是發揮索引執簡功能的工具,把眾多科研期刊中的關鍵詞以最簡要的格式顯現,使用戶能享受 “索引在手,千刊掌握”的好處,而避免花去一半的科研時間在眾多的資料堆中苦苦求索。因而,不少科研工作者贊譽索引有“天增歲月人增壽”的妙用。

10 檢索功能

索引誕生在文獻檢索困難的歷史背景里,它的檢索功能隨索引的誕生同步而生。在近二千年的索引發展史中,檢索功能的變化和發展就是它的主要內容。所以,檢索功能是索引最基本的功能。

任何文獻記錄或工作記錄一旦和索引方法掛上鈎,它就會從山窮水盡疑無路的困境中解脫出來,很快得到檢索方便的好處,機關或企業中人事檔案和工資單的 人員的索引就是如此。又如,最令旅游者頭疼的是,到了一個旅游點,買了地圖,但要尋找一個地區、一條街道或里弄,那真像大海撈針一樣的困難。當這幅地圖加 上了地名索引后,所要之地名便一檢即得了。

11 預測功能

索引中有不少數學現象,如從引文索引中統計到被引作者的論文頻率,便基本上能預測到這個專業的學術帶頭人的出現;從題錄索引中統計的課題內容,便可 預測到學術界未來研究的動向;從統計索引中出現的各種產品名稱的頻率,便能預測到市場將出現的熱門商品。這些都是索引的預測功能。

索引的創建及使用(sqlserver 2000)

為給定表或視圖創建索引。
只有表或視圖的所有者才能為表創建索引。表或視圖的所有者可以隨時創建索引,無論表中是否有數據。可以通過指定限定的數據庫名稱,為另一個數據庫中的表或視圖創建索引。

語法
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON { table | view } ( column [ ASC | DESC ] [ ,…n ] )
[ WITH < index_option > [ ,…n] ]
[ ON filegroup ]

< index_option > ::=
{ PAD_INDEX |
FILLFACTOR = fillfactor |
IGNORE_DUP_KEY |
DROP_EXISTING |
STATISTICS_NORECOMPUTE |
SORT_IN_TEMPDB
}

參數
UNIQUE

為表或視圖創建唯一索引(不允許存在索引值相同的兩行)。視圖上的聚集索引必須是 UNIQUE 索引。

在創建索引時,如果數據已存在,Microsoft? SQL Server? 會檢查是否有重復值,並在每次使用 INSERT 或 UPDATE 語句添加數據時進行這種檢查。如果存在重復的鍵值,將取消 CREATE INDEX 語句,並返回錯誤信息,給出第一個重復值。當創建 UNIQUE 索引時,有多個 NULL 值被看作副本。

如果存在唯一索引,那么會產生重復鍵值的 UPDATE 或 INSERT 語句將回滾,SQL Server 將顯示錯誤信息。即使 UPDATE 或 INSERT 語句更改了許多行但只產生了一個重復值,也會出現這種情況。如果在有唯一索引並且指定了 IGNORE_DUP_KEY 子句情況下輸入數據,則只有違反 UNIQUE 索引的行才會失敗。在處理 UPDATE 語句時,IGNORE_DUP_KEY 不起作用。

SQL Server 不允許為已經包含重復值的列創建唯一索引,無論是否設置了 IGNORE_DUP_KEY。如果嘗試這樣做,SQL Server 會顯示錯誤信息;重復值必須先刪除,才能為這些列創建唯一索引。

CLUSTERED

創建一個對象,其中行的物理排序與索引排序相同,並且聚集索引的最低一級(葉級)包含實際的數據行。一個表或視圖只允許同時有一個聚集索引。

具有聚集索引的視圖稱為索引視圖。必須先為視圖創建唯一聚集索引,然后才能為該視圖定義其它索引。

在創建任何非聚集索引之前創建聚集索引。創建聚集索引時重建表上現有的非聚集索引。

如果沒有指定 CLUSTERED,則創建非聚集索引。

說明 因為按照定義,聚集索引的葉級與其數據頁相同,所以創建聚集索引時使用 ON filegroup 子句實際上會將表從創建該表時所用的文件移到新的文件組中。在特定的文件組上創建表或索引之前,應確認哪些文件組可用並且有足夠的空間供索引使用。文件組 的大小必須至少是整個表所需空間的 1.2 倍,這一點很重要。

NONCLUSTERED

創建一個指定表的邏輯排序的對象。對於非聚集索引,行的物理排序獨立於索引排序。非聚集索引的葉級包含索引行。每個索引行均包含非聚集鍵值和一個或 多個行定位器(指向包含該值的行)。如果表沒有聚集索引,行定位器就是行的磁盤地址。如果表有聚集索引,行定位器就是該行的聚集索引鍵。

每個表最多可以有 249 個非聚集索引(無論這些非聚集索引的創建方式如何:是使用 PRIMARY KEY 和 UNIQUE 約束隱式創建,還是使用 CREATE INDEX 顯式創建)。每個索引均可以提供對數據的不同排序次序的訪問。

對於索引視圖,只能為已經定義了聚集索引的視圖創建非聚集索引。因此,索引視圖中非聚集索引的行定位器一定是行的聚集鍵。

index_name

是索引名。索引名在表或視圖中必須唯一,但在數據庫中不必唯一。索引名必須遵循標識符規則。

table

包含要創建索引的列的表。可以選擇指定數據庫和表所有者。

view

要建立索引的視圖的名稱。必須使用 SCHEMABINDING 定義視圖才能在視圖上創建索引。視圖定義也必須具有確定性。如果選擇列表中的所有表達式、WHERE 和 GROUP BY 子句都具有確定性,則視圖也具有確定性。而且,所有鍵列必須是精確的。只有視圖的非鍵列可能包含浮點表達式(使用 float 數據類型的表達式),而且 float 表達式不能在視圖定義的其它任何位置使用。

若要在確定性視圖中查找列,請使用 COLUMNPROPERTY 函數(IsDeterministic 屬性)。該函數的 IsPrecise 屬性可用來確定鍵列是否精確。

必須先為視圖創建唯一的聚集索引,才能為該視圖創建非聚集索引。

在 SQL Server 企業版或開發版中,查詢優化器可使用索引視圖加快查詢的執行速度。要使優化程序考慮將該視圖作為替換,並不需要在查詢中引用該視圖。

在創建索引視圖或對參與索引視圖的表中的行進行操作時,有 7 個 SET 選項必須指派特定的值。SET 選項 ARITHABORT、CONCAT_NULL_YIELDS_NULL、QUOTED_IDENTIFIER、ANSI_NULLS、 ANSI_PADDING 和 ANSI_WARNING 必須為 ON。SET 選項 NUMERIC_ROUNDABORT 必須為 OFF。

如果與上述設置有所不同,對索引視圖所引用的任何表執行的數據修改語句 (INSERT、UPDATE、DELETE) 都將失敗,SQL Server 會顯示一條錯誤信息,列出所有違反設置要求的 SET 選項。此外,對於涉及索引視圖的 SELECT 語句,如果任何 SET 選項的值不是所需的值,則 SQL Server 在處理該 SELECT 語句時不考慮索引視圖替換。在受上述 SET 選項影響的情況中,這將確保查詢結果的正確性。

如果應用程序使用 DB-Library 連接,則必須為服務器上的所有 7 個 SET 選項指派所需的值。(默認情況下,OLE DB 和 ODBC 連接已經正確設置了除 ARITHABORT 外所有需要的 SET 選項。)

如果並非所有上述 SET 選項均有所需的值,則某些操作(例如 BCP、復制或分布式查詢)可能無法對參與索引視圖的表執行更新。在大多數情況下,將 ARITHABORT 設置為 ON(通過服務器配置選項中的 user options)可以避免這一問題。

強烈建議在服務器的任一數據庫中創建計算列上的第一個索引視圖或索引后,盡早在服務器范圍內將 ARITHABORT 用戶選項設置為 ON。

有關索引視圖注意事項和限制的更多信息,請參見注釋部分。

column

應用索引的列。指定兩個或多個列名,可為指定列的組合值創建組合索引。在 table 后的圓括號中列出組合索引中要包括的列(按排序優先級排列)。

說明 由 ntext、text 或 image 數據類型組成的列不能指定為索引列。另外,視圖不能包括任何 text、ntext 或 image 列,即使在 CREATE INDEX 語句中沒有引用這些列。

當兩列或多列作為一個單位搜索最好,或者許多查詢只引用索引中指定的列時,應使用組合索引。最多可以有 16 個列組合到一個組合索引中。組合索引中的所有列必須在同一個表中。組合索引值允許的最大大小為 900 字節。也就是說,組成組合索引的固定大小列的總長度不得超過 900 字節。有關組合索引中可變類型列的更多信息,請參見注釋部分。

[ASC | DESC]

確定具體某個索引列的升序或降序排序方向。默認設置為 ASC。

n

表示可以為特定索引指定多個 columns 的占位符。

PAD_INDEX

指定索引中間級中每個頁(節點)上保持開放的空間。PAD_INDEX 選項只有在指定了 FILLFACTOR 時才有用,因為 PAD_INDEX 使用由 FILLFACTOR 所指定的百分比。默認情況下,給定中間級頁上的鍵集,SQL Server 將確保每個索引頁上的可用空間至少可以容納一個索引允許的最大行。如果為 FILLFACTOR 指定的百分比不夠大,無法容納一行,SQL Server 將在內部使用允許的最小值替代該百分比。

說明 中間級索引頁上的行數永遠都不會小於兩行,無論 FILLFACTOR 的值有多小。

FILLFACTOR = fillfactor

指定在 SQL Server 創建索引的過程中,各索引頁葉級的填滿程度。如果某個索引頁填滿,SQL Server 就必須花時間拆分該索引頁,以便為新行騰出空間,這需要很大的開銷。對於更新頻繁的表,選擇合適的 FILLFACTOR 值將比選擇不合適的 FILLFACTOR 值獲得更好的更新性能。FILLFACTOR 的原始值將在 sysindexes 中與索引一起存儲。

如果指定了 FILLFACTOR,SQL Server 會向上舍入每頁要放置的行數。例如,發出 CREATE CLUSTERED INDEX …FILLFACTOR = 33 將創建一個 FILLFACTOR 為 33% 的聚集索引。假設 SQL Server 計算出每頁空間的 33% 為 5.2 行。SQL Server 將其向上舍入,這樣,每頁就放置 6 行。

說明 顯式的 FILLFACTOR 設置只是在索引首次創建時應用。SQL Server 並不會動態保持頁上可用空間的指定百分比。

用戶指定的 FILLFACTOR 值可以從 1 到 100。如果沒有指定值,默認值為 0。如果 FILLFACTOR 設置為 0,則只填滿葉級頁。可以通過執行 sp_configure 更改默認的 FILLFACTOR 設置。

只有不會出現 INSERT 或 UPDATE 語句時(例如對只讀表),才可以使用 FILLFACTOR 100。如果 FILLFACTOR 為 100,SQL Server 將創建葉級頁 100% 填滿的索引。如果在創建 FILLFACTOR 為 100% 的索引之后執行 INSERT 或 UPDATE,會對每次 INSERT 操作以及有可能每次 UPDATE 操作進行頁拆分。

如果 FILLFACTOR 值較小(0 除外),就會使 SQL Server 創建葉級頁不完全填充的新索引。例如,如果已知某個表包含的數據只是該表最終要包含的數據的一小部分,那么為該表創建索引時,FILLFACTOR 為 10 會是合理的選擇。FILLFACTOR 值較小還會使索引占用較多的存儲空間。

下表說明如何在已指定 FILLFACTOR 的情況下填充索引頁。

FILLFACTOR 中間級頁 葉級頁
0 一個可用項 100% 填滿
1% -99 一個可用項 <= FILLFACTOR% 填滿
100% 一個可用項 100% 填滿

一個可用項是指頁上可以容納另一個索引項的空間。

重要 用某個 FILLFACTOR 值創建聚集索引會影響數據占用存儲空間的數量,因為 SQL Server 在創建聚集索引時會重新分布數據。

IGNORE_DUP_KEY

控制當嘗試向屬於唯一聚集索引的列插入重復的鍵值時所發生的情況。如果為索引指定了 IGNORE_DUP_KEY,並且執行了創建重復鍵的 INSERT 語句,SQL Server 將發出警告消息並忽略重復的行。

如果沒有為索引指定 IGNORE_DUP_KEY,SQL Server 會發出一條警告消息,並回滾整個 INSERT 語句。

下表顯示何時可使用 IGNORE_DUP_KEY。

索引類型 選項
聚集 不允許
唯一聚集 允許使用 IGNORE_DUP_KEY
非聚集 不允許
唯一非聚集 允許使用 IGNORE_DUP_KEY

DROP_EXISTING

指定應除去並重建已命名的先前存在的聚集索引或非聚集索引。指定的索引名必須與現有的索引名相同。因為非聚集索引包含聚集鍵,所以在除去聚集索引時,必須重建非聚集索引。如果重建聚集索引,則必須重建非聚集索引,以便使用新的鍵集。

為已經具有非聚集索引的表重建聚集索引時(使用相同或不同的鍵集), DROP_EXISTING 子句可以提高性能。DROP_EXISTING 子句代替了先對舊的聚集索引執行 DROP INDEX 語句,然后再對新的聚集索引執行 CREATE INDEX 語句的過程。非聚集索引只需重建一次,而且還只是在鍵不同的情況下才需要。

如果鍵沒有改變(提供的索引名和列與原索引相同),則 DROP_EXISTING 子句不會重新對數據進行排序。在必須壓縮索引時,這樣做會很有用。

無法使用 DROP_EXISTING 子句將聚集索引轉換成非聚集索引;不過,可以將唯一聚集索引更改為非唯一索引,反之亦然。

說明 當執行帶 DROP_EXISTING 子句的 CREATE INDEX 語句時,SQL Server 假定索引是一致的(即索引沒有損壞)。指定索引中的行應按 CREATE INDEX 語句中引用的指定鍵排序。

STATISTICS_NORECOMPUTE

指定過期的索引統計不會自動重新計算。若要恢復自動更新統計,可執行沒有 NORECOMPUTE 子句的 UPDATE STATISTICS。

重要 如果禁用分布統計的自動重新計算,可能會妨礙 SQL Server 查詢優化器為涉及該表的查詢選取最佳執行計划。

SORT_IN_TEMPDB

指定用於生成索引的中間排序結果將存儲在 tempdb 數據庫中。如果 tempdb 與用戶數據庫不在同一磁盤集,則此選項可能減少創建索引所需的時間,但會增加創建索引時使用的磁盤空間。

有關更多信息,請參見 tempdb 和索引創建。

ON filegroup

在給定的 filegroup 上創建指定的索引。該文件組必須已經通過執行 CREATE DATABASE 或 ALTER DATABASE 創建。

注釋
為表或索引分配空間時,每次遞增一個擴展盤區(8 個 8 KB 的頁)。每填滿一個擴展盤區,就會再分配一個。如果表非常小或是空表,其索引將使用單頁分配,直到向索引添加了 8 頁后,再轉而進行擴展盤區分配。若要獲得有關索引已分配和占用的空間數量的報表,請使用 sp_spaceused。

創建聚集索引要求數據庫中的可用空間大約為數據大小的 1.2 倍。該空間不包括現有表占用的空間;將對數據進行復制以創建聚集索引,舊的無索引數據將在索引創建完成后刪除。使用 DROP_EXISTING 子句時,聚集索引所需的空間數量與現有索引的空間要求相同。所需的額外空間可能還受指定的 FILLFACTOR 的影響。

在 SQL Server 2000 中創建索引時,可以使用 SORT_IN_TEMPDB 選項指示數據庫引擎在 tempdb 中存儲中間索引排序結果。如果 tempdb 在不同於用戶數據庫所在的磁盤集上,則此選項可能減少創建索引所需的時間,但會增加用於創建索引的磁盤空間。除在用戶數據庫中創建索引所需的空間外, tempdb 還必須有大約相同的額外空間來存儲中間排序結果。有關更多信息,請參見 tempdb 和索引創建。

CREATE INDEX 語句同其它查詢一樣優化。SQL Server 查詢處理器可以選擇掃描另一個索引,而不是執行表掃描,以節省 I/O 操作。在某些情況下,可以不必排序。

在運行 SQL Server 企業管理器和程序員版的多處理器計算機上,CREATE INDEX 自動使用多個處理器執行掃描和排序,與其它查詢的操作方式相同。執行一條 CREATE INDEX 語句所使用的處理器數由配置選項 max degree of parallelism 和當前的工作負荷決定。如果 SQL Server 檢測到系統正忙,則在開始執行語句之前,CREATE INDEX 操作的並發程度會自動降低。

自上一次文件組備份以來受 CREATE INDEX 語句影響的全部文件組必須作為一個單位備份。有關文件和文件組備份的更多信息,請參見 BACKUP。

備份和 CREATE INDEX 操作不相互防礙。如果正在進行備份,則在完整日志記錄模式中創建索引,而這可能需要額外的日志空間。

若要顯示有關對象索引的報表,請執行 sp_helpindex。

可以為臨時表創建索引。在除去表或終止會話時,所有索引和觸發器都將被除去。

索引中的可變類型列
索引鍵允許的最大大小為 900 字節,不過 SQL Server 2000 允許在可能包含大量可變類型列的列上創建索引,而這些列的最大大小超過 900 字節。

在創建索引時,SQL Server 檢查下列條件:

所有參與索引定義的固定數據列的總長度必須小於或等於 900 字節。當所要創建的索引只由固定數據列構成時,固定數據列的總計大小必須小於或等於 900 字節。否則將不能創建索引,且 SQL Server 將返回錯誤。

如果索引定義由固定類型列和可變類型列組成,且固定數據列滿足前面的條件(小於或等於 900 字節),則 SQL Server 仍要檢查可變類型列的總大小。如果可變類型列的最大大小與固定數據列大小的和大於 900 字節,則 SQL Server 將創建索引,不過將給用戶返回警告消息以提醒用戶:如果隨后在可變類型列上的插入或更新操作導致總大小超過 900 字節,則操作將失敗且用戶將收到運行時錯誤。同樣,如果索引定義只由可變類型列組成,且這些列的最大總大小大於 900 字節,則 SQL Server 將創建索引,不過將返回警告消息。
有關更多信息,請參見索引鍵的最大值。

在計算列和視圖上創建索引時的考慮
在 SQL Server 2000 中,還可以在計算列和視圖上創建索引。在視圖上創建唯一聚集索引可以提高查詢性能,因為視圖存儲在數據庫中的方式與具有聚集索引的表的存儲方式相同。

UNIQUE 或 PRIMARY KEY 只要滿足所有索引條件,就可以包含計算列。具體說來就是,計算列必須具有確定性、必須精確,且不能包含 text、ntext 或 image 列。有關確定性的更多信息,請參見確定性函數和非確定性函數。

在計算列或視圖上創建索引可能導致前面產生的 INSERT 或 UPDATE 操作失敗。當計算列導致算術錯誤時可能產生這樣的失敗。例如,雖然下表中的計算列 c 將導致算術錯誤,但是 INSERT 語句仍有效:

CREATE TABLE t1 (a int, b int, c AS a/b)
GO
INSERT INTO t1 VALUES (‘1’, ‘0’)
GO

相反,如果創建表之后在計算列 c 上創建索引,則上述 INSERT 語句將失敗。

CREATE TABLE t1 (a int, b int, c AS a/b)
GO
CREATE UNIQUE CLUSTERED INDEX Idx1 ON t1.c
GO
INSERT INTO t1 VALUES (‘1’, ‘0’)
GO

在通過數字或 float 表達式定義的視圖上使用索引所得到的查詢結果,可能不同於不在視圖上使用索引的類似查詢所得到的結果。這種差異可能是由對基礎表進行 INSERT、DELETE 或 UPDATE 操作時的舍入錯誤引起的。

若要防止 SQL Server 使用索引視圖,請在查詢中包含 OPTION (EXPAND VIEWS) 提示。此外,任何所列選項設置不正確均會阻止優化程序使用視圖上的索引。有關 OPTION (EXPAND VIEWS) 提示的更多信息,請參見 SELECT。

對索引視圖的限制
定義索引視圖的 SELECT 語句不得包含 TOP、DISTINCT、COMPUTE、HAVING 和 UNION 關鍵字。也不能包含子查詢。

SELECT 列表中不得包含星號 ()、’table.’ 通配符列表、DISTINCT、COUNT(*)、COUNT()、基表中的計算列和標量聚合。

非聚合 SELECT 列表中不能包含表達式。聚合 SELECT 列表(包含 GROUP BY 的查詢)中可能包含 SUM 和 COUNT_BIG();它一定包含 COUNT_BIG(*)。不允許有其它聚合函數(MIN、MAX、STDEV,…)。

使用 AVG 的復雜聚合無法參與索引視圖的 SELECT 列表。不過,如果查詢使用這樣的聚合,則優化程序將能使用該索引視圖,用 SUM 和 COUNT_BIG 的簡單聚合組合代替 AVG。

若某列是從取值為 float 數據類型或使用 float 表達式進行取值的表達式得到的,則不能作為索引視圖或表中計算列的索引鍵。這樣的列被視為是不精確的。使用 COLUMNPROPERTY 函數決定特定計算列或視圖中的列是否精確。

索引視圖受限於以下的附加限制:

索引的創建者必須擁有表。所有表、視圖和索引必須在同一數據庫中創建。

定義索引視圖的 SELECT 語句不得包含視圖、行集函數、行內函數或派生表。同一物理表在該語句中只能出現一次。

在任何聯接表中,均不允許進行 OUTER JOIN 操作。

搜索條件中不允許使用子查詢或者 CONTAINS 或 FREETEXT 謂詞。

如果視圖定義包含 GROUP BY 子句,則視圖的 SELECT 列表中必須包含所有分組依據列及 COUNT_BIG(*) 表達式。此外,CREATE UNIQUE CLUSTERED INDEX 子句中必須只包含這些列。
可以創建索引的視圖的定義主體必須具有確定性且必須精確,這類似於計算列上的索引要求。請參見在計算列上創建索引。

權限
CREATE INDEX 的權限默認授予 sysadmin 固定服務器角色、db_ddladmin 和 db_owner 固定數據庫角色和表所有者且不能轉讓。

示例
A. 使用簡單索引
下面的示例為 authors 表的 au_id 列創建索引。

SET NOCOUNT OFF
USE pubs
IF EXISTS (SELECT name FROM sysindexes
WHERE name = ‘au_id_ind’)
DROP INDEX authors.au_id_ind
GO
USE pubs
CREATE INDEX au_id_ind
ON authors (au_id)
GO

B. 使用唯一聚集索引
下面的示例為 emp_pay 表的 employeeID 列創建索引,並且強制唯一性。因為指定了 CLUSTERED 子句,所以該索引將對磁盤上的數據進行物理排序。

SET NOCOUNT ON
USE pubs
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = ‘emp_pay’)
DROP TABLE emp_pay
GO
USE pubs
IF EXISTS (SELECT name FROM sysindexes
WHERE name = ‘employeeID_ind’)
DROP INDEX emp_pay.employeeID_ind
GO
USE pubs
GO
CREATE TABLE emp_pay
(
employeeID int NOT NULL,
base_pay money NOT NULL,
commission decimal(2, 2) NOT NULL
)
INSERT emp_pay
VALUES (1, 500, .10)
INSERT emp_pay
VALUES (2, 1000, .05)
INSERT emp_pay
VALUES (3, 800, .07)
INSERT emp_pay
VALUES (5, 1500, .03)
INSERT emp_pay
VALUES (9, 750, .06)
GO
SET NOCOUNT OFF
CREATE UNIQUE CLUSTERED INDEX employeeID_ind
ON emp_pay (employeeID)
GO

C. 使用簡單組合索引
下面的示例為 order_emp 表的 orderID 列和 employeeID 列創建索引。

SET NOCOUNT ON
USE pubs
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = ‘order_emp’)
DROP TABLE order_emp
GO
USE pubs
IF EXISTS (SELECT name FROM sysindexes
WHERE name = ‘emp_order_ind’)
DROP INDEX order_emp.emp_order_ind
GO
USE pubs
GO
CREATE TABLE order_emp
(
orderID int IDENTITY(1000, 1),
employeeID int NOT NULL,
orderdate datetime NOT NULL DEFAULT GETDATE(),
orderamount money NOT NULL
)

INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (5, ‘4/12/98’, 315.19)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (5, ‘5/30/98’, 1929.04)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (1, ‘1/03/98’, 2039.82)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (1, ‘1/22/98’, 445.29)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (4, ‘4/05/98’, 689.39)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (7, ‘3/21/98’, 1598.23)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (7, ‘3/21/98’, 445.77)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (7, ‘3/22/98’, 2178.98)
GO
SET NOCOUNT OFF
CREATE INDEX emp_order_ind
ON order_emp (orderID, employeeID)

D. 使用 FILLFACTOR 選項
下面的示例使用 FILLFACTOR 子句,將其設置為 100。FILLFACTOR 為 100 將完全填滿每一頁,只有確定表中的索引值永遠不會更改時,該選項才有用。

SET NOCOUNT OFF
USE pubs
IF EXISTS (SELECT name FROM sysindexes
WHERE name = ‘zip_ind’)
DROP INDEX authors.zip_ind
GO
USE pubs
GO
CREATE NONCLUSTERED INDEX zip_ind
ON authors (zip)
WITH FILLFACTOR = 100

E. 使用 IGNORE_DUP_KEY
下面的示例為 emp_pay 表創建唯一聚集索引。如果輸入了重復的鍵,將忽略該 INSERT 或 UPDATE 語句。

SET NOCOUNT ON
USE pubs
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = ‘emp_pay’)
DROP TABLE emp_pay
GO
USE pubs
IF EXISTS (SELECT name FROM sysindexes
WHERE name = ‘employeeID_ind’)
DROP INDEX emp_pay.employeeID_ind
GO
USE pubs
GO
CREATE TABLE emp_pay
(
employeeID int NOT NULL,
base_pay money NOT NULL,
commission decimal(2, 2) NOT NULL
)
INSERT emp_pay
VALUES (1, 500, .10)
INSERT emp_pay
VALUES (2, 1000, .05)
INSERT emp_pay
VALUES (3, 800, .07)
INSERT emp_pay
VALUES (5, 1500, .03)
INSERT emp_pay
VALUES (9, 750, .06)
GO
SET NOCOUNT OFF
GO
CREATE UNIQUE CLUSTERED INDEX employeeID_ind
ON emp_pay(employeeID)
WITH IGNORE_DUP_KEY

F. 使用 PAD_INDEX 創建索引
下面的示例為 authors 表中的作者標識號創建索引。沒有 PAD_INDEX 子句,SQL Server 將創建填充 10% 的葉級頁,但是葉級之上的頁幾乎被完全填滿。使用 PAD_INDEX 時,中間級頁也填滿 10%。

說明 如果沒有指定 PAD_INDEX,唯一聚集索引的索引頁上至少會出現兩項。

SET NOCOUNT OFF
USE pubs
IF EXISTS (SELECT name FROM sysindexes
WHERE name = ‘au_id_ind’)
DROP INDEX authors.au_id_ind
GO
USE pubs
CREATE INDEX au_id_ind
ON authors (au_id)
WITH PAD_INDEX, FILLFACTOR = 10

G. 為視圖創建索引
下面的示例將創建一個視圖,並為該視圖創建索引。然后,引入兩個使用該索引視圖的查詢。

USE Northwind
GO

–Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF
GO
SET ANSI_PADDING,ANSI_WARNINGS,CONCAT_NULL_YIELDS_NULL,ARITHABORT,QUOTED_IDENTIFIER,ANSI_NULLS ON
GO

–Create view.
CREATE VIEW V1
WITH SCHEMABINDING
AS
SELECT SUM(UnitPrice*Quantity*(1.00-Discount)) AS Revenue, OrderDate, ProductID, COUNT_BIG(*) AS COUNT
FROM dbo.[Order Details] od, dbo.Orders o
WHERE od.OrderID=o.OrderID
GROUP BY OrderDate, ProductID
GO

–Create index on the view.
CREATE UNIQUE CLUSTERED INDEX IV1 ON V1 (OrderDate, ProductID)
GO

–This query will use the above indexed view.
SELECT SUM(UnitPrice*Quantity*(1.00-Discount)) AS Rev, OrderDate, ProductID
FROM dbo.[Order Details] od, dbo.Orders o
WHERE od.OrderID=o.OrderID AND ProductID in (2, 4, 25, 13, 7, 89, 22, 34)
AND OrderDate >= ‘05/01/1998’
GROUP BY OrderDate, ProductID
ORDER BY Rev DESC

–This query will use the above indexed view.
SELECT OrderDate, SUM(UnitPrice*Quantity*(1.00-Discount)) AS Rev
FROM dbo.[Order Details] od, dbo.Orders o
WHERE od.OrderID=o.OrderID AND DATEPART(mm,OrderDate)= 3
AND DATEPART(yy,OrderDate) = 1998
GROUP BY OrderDate
ORDER BY OrderDate ASC

原文來自:http://blog.csdn.net/pang040328/article/details/4164489


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM