天天看點

mysql資料庫索引原理及使用注意事項索引原理

索引原理

索引出現的原因

在使用關系型資料庫的時候,我們常常聽到一個詞:“索引”,在優化資料庫的時候,我們常常聽到有人提到添加索引可以加快資料庫的查詢速度,今天我們就來談一談它的原理。

關系型資料庫之是以叫這個名字,是因為它采用了一種名為“關系”的資料結構來存儲資料,說簡單點就是二維表格,就像我們使用navicat或者其它mysql可視化工具看到的表一樣,這樣的資料結構稱為“關系”。

采用這樣的資料結構好處就是邏輯顯而易見,但是計算機中實際的存儲結構可不是這樣的,計算機中實際的存儲結構是B+樹,樹的每一個節點存儲着一條記錄。但是這樣的缺點就是查詢的時候速度不太快,當然這個不太快是相對于一些其它的資料結構來說的。

例如,我們想象一下,我們現在在一個巨大的圖書館中,書本全是雜亂擺放的,并沒有做任何的分類,現在我們隻知道其中一本書的資訊,如果想要找到這樣一本書,無異于大海撈針。是以,為了我們查詢的快速友善,我們引入了“索引”的概念。

索引分類

索引從大體上分為兩類,第一類是聚集索引,第二類是非聚集索引,看到這裡你可能就迷惑了,“為什麼我看到的索引有好幾種,比如什麼普通索引,全文索引,唯一索引?”沒錯,這些都是索引,但是這些索引統統屬于非聚集索引,也就是我們平時所加的索引,那麼聚集索引是什麼呢?

聚集索引

聽着神秘,其實聚集索引對我們來說再熟悉不過了,它就是我們常常設定的資料庫主鍵。試想以下場景:你在第一次學習建立一個資料庫的時候有疑問,這個主鍵是什麼?你查了很多網頁,通通隻是說主鍵是唯一值,資料庫根據主鍵排序之類巴拉巴拉的話,但是你并不知道主鍵的本質就是索引。

當你設定了主鍵,你就為圖書館中的每一本書設定了書号,并且書号對應的書放在什麼位置你都一清二楚了,于是,現在你要是想找到一本書隻要簡簡單單地去對應的位置拿書就可以了。這是一種比喻,那麼實際上在我們的資料庫中,主鍵是如何實作的呢?

當我們給一個表設定了一個主鍵,此時的這張表實際上已經不是一張表了,而是變成了樹形結構(或哈希桶,非主流),而且還是平衡樹,對于InnoDB引擎來說,即使我們沒有設定主鍵,也會有一個預設的隐藏主鍵。如果對平衡樹不了解的可以去看看這篇部落格實作一個平衡二叉樹:https://blog.csdn.net/qq_37856300/article/details/83927795

當然,表變成的是平衡多叉樹而不是二叉樹,樹的每個節點的值都是主鍵的值,比如設定的id是主鍵,那麼節點的值就是id,舉個例子:

現在有這樣幾個表記錄:

mysql資料庫索引原理及使用注意事項索引原理

一旦我們設定了主鍵,就會變成下圖這樣:

mysql資料庫索引原理及使用注意事項索引原理

下面的存儲資料區依然不變,不過上面樹形結構的部分就是我們的主鍵,聚集索引部分了,可以看到,節點中存儲的都是主鍵id的值

有了這樣的結構,我們再去查詢并取出資料就要快的多了,即使是上億條資料,也隻需要查詢比較十幾次就夠了

非聚集索引

有了聚集索引,那麼為什麼會有非聚集索引呢,解釋很簡單,剛剛我們有了書号,直接使用聚集索引可以直接找到書,現在如果我們沒有了書号,隻有書的一些條件,想要根據條件找出書本,難道隻能像沒有聚集索引的時候一樣大海撈針地去尋找嗎?

不是,我們有非聚集索引。非聚集索引是通過給字段建立索引能夠快速地找到符合字段條件的主鍵值,然後拿着主鍵值再去聚集索引中找到主鍵值對應的記錄,也就是說,流程是這樣的:

非聚集索引查詢->拿到主鍵值->聚集索引使用主鍵值查詢->拿到記錄

使用索引的優缺點及注意事項

這裡的優缺點僅僅讨論非聚集索引,因為聚集索引基本上是非加不可的,是以沒有讨論的必要。

非聚集索引的優點當然就是快了,查詢的速度真的是增長了好多好多倍,缺點有兩個,第一是生成索引會占據空間,第二個是減慢了增删改的速度。

第一個其實無所謂,因為外存的成本比較低,是以花費一些空間來讓查詢速度提升完全是值得的。第二點就比較麻煩了,因為在增删改的同時還要保證索引樹的平衡,是以做了很多平衡操作,是以拖慢了速度,這就要求我們人為控制了,盡管查操作是在資料庫中使用最頻繁的操作,但是我們也不能濫用索引,對那些頻繁查找的字段,我們确實最好加上索引,但是對那些經常增删改的字段,我們在加索引的時候還是謹慎為好。

使用注意:
  1. 使用聚集索引的查詢效率要比非聚集索引的效率要高,但是如果需要頻繁去改變聚集索引的值,寫入性能并不高,因為需要移動對應資料的實體位置。
  2. 非聚集索引在查詢的時候可以的話就避免二次查詢,這樣性能會大幅提升。
  3. 不是所有的表都适合建立索引,隻有資料量大表才适合建立索引,且建立在選擇性高的列上面性能會更好。
  4. 對于查詢頻率高的字段建立索引;
  5. 對排序、分組、聯合查詢頻率高的字段建立索引;
  6. 對排序、分組、聯合查詢頻率高的字段建立索引;
  7. 索引的數目不宜太多 索引的數目不宜太多
  8. 需要将多個列設定索引時,可以采用多列索引
  9. 選擇唯一性索引
  10. 盡量使用資料量小的索引
  11. 盡量使用字首來索引

    如果索引字段的值很長,最好使用值的字首來索引。例如,TEXT和BLOG類型的字段,進行全文檢索會很浪費時間。如果隻檢索字段的前面的若幹個字元,這樣可以提高檢索速度。

  12. 删除不再使用或者很少使用的索引.