簡析數據庫索引
今天我們來聊一聊關於 聚簇索引和非聚簇索引的問題;
剛開始學數據庫SQL的時候,就知道有主鍵啊(Primary-key),外鍵啊(Foreign-key)啥的,連個表查詢就已經不清楚是要on 那幾個字段了,在數據量不太大的情況下,根本不會考慮索引的問題了,然後,隨著大數據時代的到來,數據量大了,沒有索引那是要不得的啊,客戶又吐槽了,你知不知道,你知不知道,我等到花兒都謝鳥。。。。。沒有索引,完全依賴生硬的where條件,達到百萬級數據記錄之後,如果沒有主鍵,頁面加載慢的一比,查詢頁面分分鐘可能被用戶直接關閉,剩下的你就等著 產品經理的一頓又一頓吐槽了吧。。。。。
OK,閑話不多扯了,言歸正傳,那我們來了解一下:
(一下僅供新人學習交流與個人體會,數據庫大神可直接無視,若有不當之處,歡迎大神雅正.)
- 什麽是索引;
- 什麽是聚簇索引和非聚簇索引;
- 為什麽要建索引;
- 動手試試,看看代碼怎麽敲的;
- 性能比較與分析;
什麽是索引.
我們來看看比較大眾的定義,OK,那就直接百度百科吧:"索引是對數據庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問數據庫表中的特定信息。" 看中心語-關鍵詞[一種結構],說到底索引就是對數據列的值進行結構化排序的一個東西.
通俗點講吧. 還記得大學軍訓的時候嗎,大夥第一天穿上迷彩服到運動場或者野外軍訓場地進行軍訓的時候,一般都是亂紮堆的吧,亂成一團,結果軍訓的教官來了,教官一看大夥,有男有女,有高有矮 幾分鐘很快就把大夥排成了m行n列的方針,盡然有序,高低有序;而且沒多久教官還能很快滴說出大家的名字,‘x行y列(或者xx號學員),王大錘,出列!’ 一聲令下,王大錘就從隊列中走出來了,...
這段場景中,教官就是軍訓場地上最好的【索引】;
什麽是聚簇索引和非聚簇索引
有了索引的概念認知,聚簇索引和非聚簇索引就好理解了,說一個最簡單的例子吧;
【聚簇索引】
平時習慣逛圖書館的童鞋可能比較清楚,如果你要去圖書館借一本書,最開始是去電腦裏面查書名然後根據書名來定位藏書在那個區,哪個書櫃,哪一行,第多少本。。。清晰明確,一目了然,因為藏書的結構與圖書室的位置,書架的順序,書本的擺放順序與書籍的編號都是從大到小一致的順序擺放的,所以很容易找到。比如,你的目標藏書在C區2櫃3排5倉,那麽你走到B區你就很快知道前面就快到了C區了,你直接奔著2櫃區就能找到了。 這就是雷同於聚簇索引的功效了,聚簇索引,實際存儲的循序結構與數據存儲的物理機構是一致的,所以通常來說物理順序結構只有一種,那麽一個表的聚簇索引也只能有一個,通常默認都是主鍵,設置了主鍵,系統默認就為你加上了聚簇索引,當然有人說我不想拿主鍵作為聚簇索引,我需要用其他字段作為索引,當然這也是可以的,這就需要你在設置主鍵之前自己手動的先添加上唯一的聚簇索引,然後再設置主鍵,這樣就木有問題啦。
總而言之,聚簇索引是順序結構與數據存儲物理結構一致的一種索引,並且一個表的聚簇索引只能有唯一的一條;
【非聚簇索引】
同樣的,如果你去的不是圖書館,而是某城市的商業性質的圖書城,那麽你想找的書就擺放比較隨意了,由於商業圖書城空間比較緊正,藏書通常按照藏書上架的先後順序來擺放的,所以如果查詢到某書籍放在C區2櫃3排5倉,但你可能要繞過F區,而不是A.B.C.D...連貫一致的,也可能同在C區的2櫃,書櫃上第一排是計算機類的書記,也可能最後一排就是醫學類書籍;
那麽對照著來看非聚簇索引的概念就比較好理解了,非聚簇索引記錄的物理順序與邏輯順序沒有必然的聯系,與數據的存儲物理結構沒有關系;一個表對應的非聚簇索引可以有多條,根據不同列的約束可以建立不同要求的非聚簇索引;
為什麽要建索引
這個問題肯定很簡單啦,看了上面的描述就知道了,肯定是為了加快找到目標數據的速度,節約查找話費的時間啦,用數據庫屬於來描述就是 :
建立索引的目的是加快對表中記錄的查找或排序。
但是話又說回來了,有了索引是不是就以為的數據的查詢快得不要不要的,。。。。
或者說,添加了索引之後,查詢速度一定回避沒有添加索引的情況下更快? 我看未必哦。。。
我們還是先了解一下 建立索引需要付出的代價和帶來的弊端:
一.增加了數據庫的存儲空間,
二.在插入和修改數據時要花費較多的時間(因為索引也要隨之變動);
我們假設在一張表中的一條記錄在磁盤上占用1KB話,我們對其中10B的一個字段建立索引,那麽該記錄對應的索引塊的大小只有10B,如果一張表的的數據量比較大,大約100,000條,那麽用來存儲索引耗費的空間就是100,000X10B=1000,000B=10000KB=1MB,換句話說,這張白表也因為這個索引的建立而多使用了大約1MB的存儲空間,當然對與大批量數據來說,這麽點空間是不足為道的。但事實是,索引確實耗費了更多空間;
關於第二條我就不用贅述了,這個文字描述已經說的很清楚;
還有就是,對某些場景下,數據量不是特別大的情況下,對於某些添加索引的行為,不但不能優化查詢速度,反而會減慢查詢速度,當然,如果索引的建立不恰當,所選擇建立索引的字段不合適,也可能會削弱查詢速度,當然在數據量不大的情況下,基於SQL服務器本身強大的處理能力,這種削弱表現是非常微弱的,但是一旦數據量大起來,原本可以不需要考慮索引就能很快查詢出來數據的,結果因為添加了索引反而加重了查詢數據的消耗,不恰當的索引方式造成的影響就會表現的很明顯;
所以,索引不是萬能的,某些情況下,添加索引可能比不添加索引更慢!
最後引用別人[姜敏(http://www.cnblogs.com/aspnet2008/)]曾經總結過的幾句話來描述一下索引的使用原則:
總結索引使用原則:
不要索引數據量不大的表,對於小表來講,表掃描的成本並不高。
不要設置過多的索引,在沒有聚集索引的表中,最大可以設置249個非聚集索引,過多的索引首先會帶來更大的磁盤空間,而且在數據發生修改時,對索引的維護是特別消耗性能的。
合理應用復合索引,有某些情況下可以考慮創建包含所有輸出列的覆蓋索引。
對經常使用範圍查詢的字段,可能考慮聚集索引。
避免對不常用的列,邏輯性列,大字段列創建索引。
簡析數據庫索引