索引的建立

CREATE   INDEX  
  爲給定表或視圖創建索引。  
   
  只有表或視圖的所有者才能爲表創建索引。表或視圖的所有者可以隨時創建索引,無論表中是否有數據。可以通過指定限定的數據庫名稱,爲另一個數據庫中的表或視圖創建索引。  
   
  語法  
  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&reg;   SQL   Server&#8482;   會檢查是否有重複值,並在每次使用   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(<expression>)、基表中的計算列和標量聚合。    
   
  非聚合   SELECT   列表中不能包含表達式。聚合   SELECT   列表(包含   GROUP   BY   的查詢)中可能包含   SUM   和   COUNT_BIG(<expression>);它一定包含   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 .........
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章