mysql資料庫索引原理及使用注意事項
索引原理
索引出現的原因
在使用關係型資料庫的時候,我們常常聽到一個詞:“索引”,在優化資料庫的時候,我們常常聽到有人提到新增索引可以加快資料庫的查詢速度,今天我們就來談一談它的原理。
關係型資料庫之所以叫這個名字,是因為它採用了一種名為“關係”的資料結構來儲存資料,說簡單點就是二維表格,就像我們使用navicat或者其它mysql視覺化工具看到的表一樣,這樣的資料結構稱為“關係”。
採用這樣的資料結構好處就是邏輯顯而易見,計算機中儲存的資料結構基本上就是要呈現給使用者來看的結構。但是這樣的缺點就是查詢的時候速度不太快,當然這個不太快是相對於一些其它的資料結構來說的。
例如,我們想象一下,我們現在在一個巨大的圖書館中,書本全是雜亂擺放的,並沒有做任何的分類,現在我們只知道其中一本書的資訊,如果想要找到這樣一本書,無異於大海撈針。因此,為了我們查詢的快速方便,我們引入了“索引”的概念。
索引分類
索引從大體上分為兩類,第一類是聚集索引,第二類是非聚集索引,看到這裡你可能就迷惑了,“為什麼我看到的索引有好幾種,比如什麼普通索引,全文索引,唯一索引?”沒錯,這些都是索引,但是這些索引統統屬於非聚集索引,也就是我們平時所加的索引,那麼聚集索引是什麼呢?
聚集索引
聽著神祕,其實聚集索引對我們來說再熟悉不過了,它就是我們常常設定的資料庫主鍵。試想以下場景:你在第一次學習建立一個數據庫的時候有疑問,這個主鍵是什麼?你查了很多網頁,通通只是說主鍵是唯一值,資料庫根據主鍵排序之類巴拉巴拉的話,但是你並不知道主鍵的本質就是索引。
當你設定了主鍵,你就為圖書館中的每一本書設定了書號,並且書號對應的書放在什麼位置你都一清二楚了,於是,現在你要是想找到一本書只要簡簡單單地去對應的位置拿書就可以了。這是一種比喻,那麼實際上在我們的資料庫中,主鍵是如何實現的呢?
當我們給一個表設定了一個主鍵,此時的這張表實際上已經不是一張表了,而是變成了樹形結構(或雜湊桶,非主流),而且還是平衡樹。如果對平衡樹不瞭解的可以去看看這篇部落格實現一個平衡二叉樹:https://blog.csdn.net/qq_37856300/article/details/83927795
當然,表變成的是平衡多叉樹而不是二叉樹,樹的每個節點的值都是主鍵的值,比如設定的id是主鍵,那麼節點的值就是id,舉個例子:
現在有這樣幾個表記錄:
當我們設定主鍵之前,資料庫中的結構就是如圖這樣:
現在這就是我們的資料儲存區的模樣
但是一旦我們設定了id,就會變成下圖這樣:
下面的儲存資料區依然不變,不過上面樹形結構的部分就是我們的主鍵,聚集索引部分了,可以看到,節點中儲存的都是主鍵id的值
有了這樣的結構,我們再去查詢並取出資料就要快的多了,即使是上億條資料,也只需要查詢比較十幾次就夠了
非聚集索引
有了聚集索引,那麼為什麼會有非聚集索引呢,解釋很簡單,剛剛我們有了書號,直接使用聚集索引可以直接找到書,現在如果我們沒有了書號,只有書的一些條件,想要根據條件找出書本,難道只能像沒有聚集索引的時候一樣大海撈針地去尋找嗎?
不是,我們有非聚集索引。非聚集索引是通過給欄位建立索引能夠快速地找到符合欄位條件的主鍵值,然後拿著主鍵值再去聚集索引中找到主鍵值對應的記錄,也就是說,流程是這樣的:
非聚集索引查詢->拿到主鍵值->聚集索引使用主鍵值查詢->拿到記錄
使用索引的優缺點及注意事項
這裡的優缺點僅僅討論非聚集索引,因為聚集索引基本上是非加不可的,所以沒有討論的必要。
非聚集索引的優點當然就是快了,查詢的速度真的是增長了好多好多倍,缺點有兩個,第一是生成索引會佔據空間,第二個是減慢了增刪改的速度。
第一個其實無所謂,因為外存的成本比較低,所以花費一些空間來讓查詢速度提升完全是值得的。第二點就比較麻煩了,因為在增刪改的同時還要保證索引樹的平衡,所以做了很多平衡操作,因此拖慢了速度,這就要求我們人為控制了,儘管查操作是在資料庫中使用最頻繁的操作,但是我們也不能濫用索引,對那些頻繁查詢的欄位,我們確實最好加上索引,但是對那些經常增刪改的欄位,我們在加索引的時候還是謹慎為好。
使用注意:
- 使用聚集索引的查詢效率要比非聚集索引的效率要高,但是如果需要頻繁去改變聚集索引的值,寫入效能並不高,因為需要移動對應資料的物理位置。
- 非聚集索引在查詢的時候可以的話就避免二次查詢,這樣效能會大幅提升。
- 不是所有的表都適合建立索引,只有資料量大表才適合建立索引,且建立在選擇性高的列上面效能會更好。
- 對於查詢頻率高的欄位建立索引;
- 對排序、分組、聯合查詢頻率高的欄位建立索引;
- 對排序、分組、聯合查詢頻率高的欄位建立索引;
- 索引的數目不宜太多 索引的數目不宜太多
- 需要將多個列設定索引時,可以採用多列索引
- 選擇唯一性索引
- 儘量使用資料量小的索引
- 儘量使用字首來索引
如果索引欄位的值很長,最好使用值的字首來索引。例如,TEXT和BLOG型別的欄位,進行全文檢索會很浪費時間。如果只檢索欄位的前面的若干個字元,這樣可以提高檢索速度。 - 刪除不再使用或者很少使用的索引.