從CREATE開始數據庫
隨約束建立的隱含索引post
當向表中添加以下兩種約束之一時,就會建立隱含索引。測試
CREATE INDEX語句所作的事情與其聽上去同樣-用於在指定表或視圖上基於聲明的列建立索引:優化
CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX <index name> ON <table or view name>(<column name> [ASC|DESC][,...n]) INCLUDE (<column name> [,...n]) [ WITH [PAD_INDEX = {ON | OFF}] [[,] FILLFACTOR = <fillfactor>] [[,] IGNORE_DUR_KEY = {ON | OFF}] [[,] DROP_EXISTING = {ON | OFF}] [[,] STATISTICS_NORECOMPUTE = {ON | OFF}] [[,] SORT_IN_TEMPDB = {ON | OFF}] [[,] ONLINE = {ON | OFF}] [[,] ALLOW_ROW_LOCKS = {ON | OFF}] [[,] ALLOW_PAGE_LOCKS = {ON | OFF}] [[,] MAXDOP = <maxinum degree of parallelism> ] [ON {<filegroup> | <partition scheme name> | DEFAULT}]
CREATE INDEX語句必須隨表或者視圖出現,而且須要聲明列所在(ON)的表。下面解釋個選項的做用ui
一、ASC/DESCspa
這兩個選項容許爲索引選擇升序和降序排列順序。默認選項爲ASC,它是升序。指針
爲何須要升序和降序兩個選項呢?不是反序查看索引不就好了嗎?可是若是一列按升序排列,可是其餘列要求按降序排列,怎麼辦呢?由於索引的列是存儲在一塊兒的,因此對一列反向查看索引也將倒轉其餘列的順序。若是顯示地聲明某一列是升序,而另外一列是降序,那麼將直接在索引的物理數據中倒轉第二列-忽然間就沒必要改變訪問數據的方式了。code
二、INCLUDE對象
這是SQL Server2005及後續版本支持的選項。它的目的是爲覆蓋查詢(covered queries)提供更好的支持。blog
當包含(INCLUDE)列而不是將列放在ON列表上時,SQL Server僅僅在索引的葉級上添加它們。由於在索引葉級上的每一行對應於一個數據行,因此所作的事情在本質上是將更多的原始數據包含在索引的葉級上。這樣作有一個好處,由於SQL Server在有了它實際須要的內容就中止工做。SQL Server在遍歷索引時沒有繼續訪問實際的數據行就找到所需的全部數據,那麼就沒必要再到達數據行。經過在索引中包含特定的列,能夠在葉級「覆蓋」利用該特定索引的查詢,從而節省了與使用索引指針到達數據頁相關的I/O。實際是,好比你爲一個日期列建立索引,可是INCLUDE一個訂單ID列。那麼查找某日期的訂單ID,就沒必要再到實際數據行了,由於在索引中就有了所需的數據。可是注意不要濫用該選項,當包含列時,將增長索引頁的葉級的大小。這意味着每頁中的行數將更少,所以須要更多的I/O來查看相同數量的行。結果多是,加快了一個查詢的同時可能減慢了其餘的查詢。要考慮對系統各個部分的影響,而不是僅僅考慮某個時候正在使用的特定查詢。
三、WITH
WITH很是簡單-它只是告訴SQL Server將要提供一個或者多個跟在後面的選項。
四、PAD_INDEX
該選項肯定了第一次建立索引時,索引的非葉級頁將有多滿(用百分比表示)。不用在PAD_INDEX中聲明百分比,由於將使用後面的FILLTACTOR選項指定的百分比。設置不帶有FILLFACTOR選項的PAD_INDEX=ON將是沒有意義的。
五、FILLFACTOR
當SQL Server第一次建立索引時,默認狀況下將盡量地將頁填滿,僅留兩個記錄的控件,能夠將FILLTACTOE設置爲在0-100之間的任意值。一旦索引構造完成,這個數字將表示頁相對滿的程度的百分比。可是在進行頁拆分時,數據將仍然在兩頁之間對半分佈-除了按期重建索引外,不能不斷地控制填充百分比。
當須要調整頁密度的時候,使用FILLTACTOR須要從如下幾方面考慮:
六、IGNORE_DUP_KEY
IGNORE_DUP_KEY選項幾乎是一種迴避系統的方法。簡而言之,它使得惟一約束與其應有的操做方式有些不一樣。
一般,惟一約束(或惟一索引)不容許任何種類的重複-若是事務嘗試基於定義爲惟一的列建立重複值,那麼事務將被回滾而且拒絕。然而,一旦設置了IGNORE_DUP_KEY選項,就將獲得混合的行爲。仍然接收錯誤信息,可是錯誤將僅僅是一種警告-記錄仍然沒有被插入。
從IGNORE_DUP_KEY的角度看,不能會事務進行回滾(錯誤還是警告錯誤,而不是關鍵錯誤),但重複的行將被拒絕。
一句話,這個東西的態度是,重複行徹底沒問題,可是你要有一個該值的行存在就OK了(插入時,重複行被忽略,仍是所有都不容許插入)。
當你建立惟一索引時,你能夠指定IGNORE_DUP_KEY選項,所以本文最開始建立惟一索引的選項能夠是:
CREATE UNIQUE NONCLUSTERED INDEX AK_Product_Name ON Production.Product ( [Name] ) WITH ( IGNORE_DUP_KEY = OFF );
IGNORE_DUP_KEY這個名字容易讓人誤會。惟一索引存在時重複的值永遠不會被忽略。更準確的說,惟一索引中永遠不容許存在重複鍵。這個選項的做用僅僅是在多列插入時有用。
好比,你有兩個表,表A和表B,有着徹底相同的結構。你可能提交以下語句給SQL Server。
INSERT INTO TableA SELECT * FROM TableB;
SQL Server會嘗試將全部表B中的數據插入表A。但若是由於惟一索引拒絕表B中含有和表A相同的數據插入A怎麼辦?你是但願僅僅重複數據插入不成功,仍是整個INSERT語句不成功?
這個取決於你設定的IGNORE_DUP_KEY參數,當你建立惟一索引時,經過設置設個參數能夠設定當插入不成功時怎麼辦,設置IGNORE_DUP_KEY的兩種參數解釋以下:
IGNORE_DUP_KEY=OFF
整個INSERT語句都不會成功並彈出錯誤提示,這也是默認設置。
IGNORE_DUP_KEY=OFF
只有那些具備重複鍵的行不成功,其它全部的行會成功。並彈出警告信息。
IGNORE_DUP_KEY 選項僅僅影響插入語句。而不會被UPDATE,CREATE INDEX,ALTER INDEX所影響。這個選項也能夠在設置主鍵和惟一約束時進行設置。
七、DROP_EXISTING
若是指定DROP_EXISTING選項,那麼若是以前已經存在同名索引將在構造新索引以前被刪除。當和羣集索引一塊兒使用該選項時,這個選項比簡單刪除並從新建立現有的索引更加有效。若是從新建立與現有索引徹底匹配的索引,那麼SQL Server知道它不須要涉及非羣集索引,然而爲了適應不一樣的行位置,顯式刪除和建立將致使從新構建全部非羣集索引兩次。若是使用DROP_EXISTING改變索引的結構,那麼NCI只被從新構建一次,而不是兩次。
八、STATISTICS_NORECOMPUTE
默認狀況下,SQL Server試圖自動化在表和索引上更新統計信息的過程。經過選擇該選項,表示將由本身手動負責更新統計信息。爲了關閉這個選項,須要運行UPDATESTATISTICS命令,但不使用NORECOMPUTE。
強烈建議不要使用該選項,由於查詢優化器使用索引上的統計信息來指出索引對於給定的查詢有多大用處。隨着表中數據大量增多或減小,以及列特定值改變。索引上的統計信息會不斷變化。基於這兩點,能夠知道不更新統計信息則查詢優化器將基於過期的信息運行查詢,打開自動統計信息功能意味着統計信息將週期地更新(多長時間更新一次取決於對錶更新的本質和頻繁程度)。相反關閉自動更新統計信息意味着信息會過期,或者須要設定計劃手動運行UPDATE STATISTICS。
九、SORT_IN_TEMPDB
只有在tempdb存儲在與包含新索引的數據庫物理上分離的驅動器上時,該選項纔有意義。爲何?
當SQL Server創建索引時,它必須執行多個讀操做以處理各類索引構造步驟。
一、遍歷全部的數據,構建對應於實際數據每一行的葉行。相似於實際數據和最後的索引,這些內容進入用於臨時存儲的頁。這些中間頁不是最終的索引頁,而是每次排序緩衝器已滿時臨時存儲的位置。
二、經過這些中間頁單獨運行,以將他們合併到最終葉級頁。
三、當填充葉級頁時,構建非葉級頁。
若是沒有使用SORT_IN_TEMPDB選項,那麼中間頁將被寫入在其中存儲數據庫的相同物理文件中。這意味着實際數據的讀操做必須與構建過程的寫操做競爭。這兩種狀況形成磁頭須要移動到一個不一樣的位置(讀和寫)。結果是磁頭常常地來回移動-這會花費時間。
另外一方面,若是使用SORT_IN_TEMPDB,那麼中間頁將被寫入tempdb中,而不是數據庫本身的文件。若是它們在單獨的物理驅動器上,這意味着在索引構建的讀和寫操做之間沒有競爭。可是要牢記,只有在tempdb位於與數據庫文件分離的獨立物理驅動器上,這纔會有效。不然,只是名義上發生改變,而I/O競爭仍然是問題。
若是要使用SORT_IN_TEMPDB,那麼確保在tempdb中有用於支持大文件的足夠空間。
十、ONLINE
若是將這個選項設置爲ON,那麼它將強制表對於通常的訪問保持有效,而且不建立任何阻止用戶使用索引和/表的鎖。默認狀況下,全索引操做將得到所需的鎖(最終獲得表鎖),以便對錶進行徹底和有效的訪問,然而,反作用是這將會阻止用戶(這是矛盾的:一方面可能正在創建索引以使數據庫更爲有用,可是同時又使表變得不可用)。
十一、ALLOW ROW/PAGE LOCKS
這裏的ALLOW設置用於肯定索引是否容許行鎖和頁鎖。
十二、MAXDOP
該選項用於爲構建索引覆蓋關於最大並行度的系統設置。並行度是指將有多少個進程用於一個數據庫操做。有一個稱爲最大並行度的系統設置,容許限制每一個操做中的處理器數。索引建立的MAXDOP選項容許將並行度設置爲高於或者低於基本系統設置。只要合適就行。
1三、ON
SQL Server容許經過使用ON選項將數據和索引單獨存放。這樣作有如下優勢:
下面簡單補充下XML索引的概念。
XML索引是SQL Server2005新增功能。
除了IGNORE_DUP_KEY和ONLINE以外,XML的建立語法支持前面的CREATE語句中所看到的全部相同選項。
在SQL Server中,能夠再類型爲XML的列上建立索引。這樣作的主要要求以下。
一、主XML索引
在XML索引上建立的第一個索引必須聲明爲"主索引"。當建立主索引時,SQL Server建立一個新的羣集索引,這個羣集索引將基表的羣集索引和來自任何指定的XML節點的數據組合在一塊兒。
二、輔助XML索引
相似於指向羣集索引的羣集鍵的非羣集索引,輔助XML索引以很類似的方法指向主XML索引。一旦建立了主XML索引,就只能在XML列上建立多達248個以上的XML索引。
ALTER INDEX命令在其用來作什麼方面多少有些欺騙性。截止到如今,ALTER命令老是與修改對象的定義有關。例如ALTER表以添加或禁用約束和列。ALTER INDEX是不一樣的-該命令與維護有關,而與結構徹底不相干。若是需修改索引的組成,那麼只能DROP而後CREATE索引,或者用DROP_EXISTING=ON選項CREATE並使用索引。
ALTER INDEX的語法相似於下面這樣:
ALTER INDEX {<name of index> | ALL} ON<table or view name> { REBUILD [[ WITH ( [PAD_INDEX = {ON | OFF}] | [[,] FILLFACTOR = <fillfactor> | [[,] SORT_IN_TEMPDB = { ON | OFF }] | [[,] IGNORE_DUP_KEY = { ON | OFF }] | [[,] STATISTICS_NORECOMPUTE = { ON | OFF }] | [[,] ONLINE = { ON| OFF }] | [[,] ALLOW_ROW_LOCKS = { ON | OFF }] | [[,] ALLOW_PAGE_LOCKS = { ON | OFF }] | [[,] MAXDOP = <max degree of parallelism> )] |[ PARTITION = <partition number> [ WITH (< partition rebuild index option> [,...N])]]] | DISABLE | REORGANIZE [ PARTITION = <partition number> ] [ WITH (LOB_COMPACTION = { ON | OFF })] | SET ([ ALLOW_ROW_LOCKS = { ON | OFF} ] | [[,] ALLOW_PAGE_LOCKS = { ON | OFF } ] | [[,] IGNORE_DUP_KEY = { ON | OFF } ] | [[,] STATISTICS_NORECOMPUTE = { ON | OFF }] ) }[;]
其中一些選項與CREATE INDEX命令相同,所以這裏將略過對這些選項的從新定義。除此以外,至關多的ALTER特定選項都是細節性的,且與處理碎片之類的事情有關。下面解釋下參數
一、索引名
若是想維護一個特定的索引能夠指定該索引,或者使用ALL代表想要維護與指定的表相關聯的全部索引。
二、表名或視圖名
要在其上維護的特定對象(表或視圖)的名稱。注意,必須是一個特定的表(能夠給它提供一個列表,而後說「請處理全部這些!」)。
三、REBULD
若是使用該選項運行ALTER INDEX,那麼將徹底丟棄舊的索引並從新生成新的索引。結果是真正優化的索引,其中全部葉級和非葉級的頁都按照定義進行了從新構建。若是是羣集索引,那麼也會從新組織物理數據。
默認狀況下,頁將被從新組織爲差兩行滿。和CREATE TABLE語法同樣,能夠將FILLFACTOR設置爲0~100以前的任何值。該值是在數據庫完成從新組織後頁被填滿的程度(以百分比表示)。但在進行頁拆分時,數據將被對半分部在兩個頁上-除了按期重建索引外,不得不斷控制填充的百分比。
要當心使用該選項,一旦開始REBUILD,在完成索引重建錢,正在使用的索引實際上就沒有了。依賴該索引的全部查詢可能會變得異常慢。對於這類事情,首先須要在離線系統上測試,以瞭解整個過程將花多少時間。而後,計劃在非高峯時段運行。
四、DISABLE
該選項名副其實,只是方式有些過激。若是該命令的所有做用只是爲了讓索引離線,直至您決定了進一步要作什麼,則它是不錯的選擇,但它實際會把索引標記爲不可用,一旦禁用了某個索引,在從新激活以前,必須重建索引(不是從新組織,而是重建)。
若是對錶禁用了羣集索引,那麼也會禁用表。數據仍會保留,但在重建羣集索引錢,不能被全部索引(由於他們都依賴羣集索引)訪問。
五、REORGANIZE
若是從新組織索引,就獲得了比徹底重建索引稍遜一點的徹底優化,但這種方法能夠聯機進行(用戶仍能使用索引)。
稍遜一點指的是什麼?實際上是REORGANIZE只在索引的葉級起做用,而不觸及非葉級。這意味着未得到徹底優化。可是,對於大部分的索引而言,那不是真正產生碎片的地方。
若是不斷地從新分析狀況和添加索引,那麼也不要忘記刪除索引。記住在插入索引上的系統開銷。
刪除索引的語法以下:
DROP INDEX <table or view name>.<index name>
這樣就能夠刪除索引了。