當咱們在設計數據庫的時候,對錶的一些屬性有時會加上索引,但索引爲何能提升檢索速率呢?是否是用了索引就必定能夠提升效率呢?不一樣索引之間有什麼區別呢?搞懂這些問題是靈活運用索引的必備條件。接下來,咱們將一 一進行討論。數據庫
索引也分爲不一樣的種類,並且也有不一樣的分類方法,比較經常使用的是普通索引和彙集索引。緩存
其實對某字段創建了索引就至關因而對該字段新創建了一個表,這個表裏的元素是安照這個字段有序排列。這樣有什麼好處呢?好處就在於若是咱們select的時候要搜索該字段,那就會在這個索引表中先查找,由於索引表是有序的,因此在檢索該字段的時候就是二分搜索,速度天然會比在原表上快,而後若是我只須要這一個字段的話,查詢就能夠結束了,但若是還須要除索引字段的其餘字段的話,那麼就會根據這個索引表的字段對應到主表中,而後再獲取。
看了上面講的,是否是感受有點迷茫?下面看一下圖就會清晰不少。
(圖片來源於百度)
你們能夠看到這裏咱們以Col2創建索引以後右邊有一顆二叉樹,可能你們會問不是說好了是一張表嗎,怎麼又是二叉樹了,好吧表自己就是一種樹形的數據結構存儲,雖然實際上不多會選取二叉樹,但此處方便講解。能夠看到Col2單獨的一棵樹,而後每個節點對過來是一條記錄,若是咱們執行 select Col2 from tablename where Col2=34;那麼直接在右邊的樹中二叉搜索,找到了就能夠返回了。若是咱們執行 select * from tablename where Col2=34;那麼能夠看到須要的不只僅是Col2這一個字段,那麼仍是先在二叉樹中查找,而後找到了以後對應到主表中,而後返回整條記錄。數據結構
經過上面的圖咱們能夠看到,索引的本質其實就是新建了一張表,而表本質上的數據結構就是樹形結構,因此索引也是樹形結構。但實際運用中並無誰用紅黑樹,avl樹這種數據結構,通常是b+樹,接下來給你們大體介紹一下b+樹的構成。
(圖片來源於百度)
b+樹在構建時和咱們以前提到的二三樹很像,只是有一些改進,b+樹的非葉子節點不包含value的信息,也就是說非葉子結點只起到一個導航的做用,全部的value放在了葉子結點裏,這樣因爲B+樹在內部節點上不包含數據信息,所以在內存頁中可以存放更多的key。 數據存放的更加緊密,具備更好的空間局部性。所以訪問葉子節點上關聯的數據也具備更好的緩存命中率。一般會將b+樹進行優化,增長順序訪問指針。
(圖片來源於百度0)
在B+Tree的每一個葉子節點增長一個指向相鄰葉子節點的指針,就造成了帶有順序訪問指針的B+Tree。作這個優化的目的是爲了提升區間訪問的性能,例如圖中若是要查詢key爲從18到49的全部數據記錄,當找到18後,只需順着節點和指針順序遍歷就能夠一次性訪問到全部數據節點,極大提到了區間查詢效率。
能夠看到b+樹對於表的存儲是一種很方便的數據結構。那麼爲何不用紅黑樹呢,由於數據量大的時候,會致使這種二叉樹深度太深,io次數會不少,層數不多的b+樹能夠有效下降io次數。性能
彙集索引和普通索引是不同的,彙集索引是指數據庫錶行中數據的物理順序與鍵值的邏輯(索引)順序相同。一個表只能有一個彙集索引,由於一個表的物理順序只有一種狀況。意思就是說上面的普通索引咱們能夠看到是另建了一個表,而後當查詢到了索引沒有覆蓋到的字段的時候是將這個字段映射到了主表中而後進行查詢的。而彙集索引創建後主表自己就會按照這個索引的結構來存儲,意思就是說主表直接就按這個來存了。這也是爲何彙集索引必定是惟一的緣由,由於一張表中只能有一種存儲方式。優化
兩種索引誰更快呢?這固然是沒有懸念的,彙集索引更快咯,由於普通索引查到沒有覆蓋的字段的時候須要向主表中映射過去,而後再獲取,而彙集索引由於其自己就包含了全部數據,因此一次就好~設計
在咱們新建一個表時,若是沒有定義主鍵,那麼表格的數據是順序線性存儲的,在定義的主鍵以後,由於主鍵默認有索引,而且在不少平臺上默認是彙集索引,因此在主鍵定義的時候就會把整個表變爲一個樹形結構(若是主鍵是彙集索引),但要知道的是主鍵不必定是彙集索引,也能夠是普通索引,只是不少平臺默認爲彙集,不要盲目劃等號。指針
那麼索引既然這麼快是否是越多越好呢?不存在的,由於索引自己是一個數據表,那麼在插入或刪除的時候就涉及到了索引表的改變,b+樹的插入刪除涉及到不少節點操做,或許會消耗不少時間。因此咱們對於常改變的字段不宜建索引,而對於改動較少的字段就很合適,在設計表的時候咱們要靈活選取,才能高效。blog