mysql 索引原理

1 索引介紹:算法

需求:數據庫

  通常的應用系統,讀寫比例在10:1左右,並且插入操做和通常的更新操做不多出現性能問題,在生產環境中,咱們遇到最多的,也是最容易出問題的,仍是一些複雜的查詢操做,所以對查詢語句的優化顯然是重中之重。
提及加速查詢,就不得不提到索引了。數據結構

索引:性能

   簡單的說,至關於圖書的目錄,能夠幫助用戶快速的找到須要的內容.優化

   在MySQL中也叫作「鍵」,是存儲引擎用於快速找到記錄的一種數據結構。可以大大提升查詢效率。特別是當數據量很是大,查詢涉及多個表時,使用索引每每能使查詢速度加快成千上萬倍.spa

本質:設計

  索引本質:經過不斷地縮小想要獲取數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,咱們能夠老是用同一種查找方式來鎖定數據。指針

2 索引方法排序

             1. B+TREE 索引索引

 

  B+樹是一種經典的數據結構,由平衡樹二叉查找樹結合產生,它是爲磁盤或其它直接存取輔助設備而設計的一種平衡查找樹,在B+樹中,全部的記錄節點都是按鍵值大小順序存放在同一層的葉節點中,葉節點間用指針相連,構成雙向循環鏈表,非葉節點(根節點、枝節點)只存放鍵值,不存放實際數據。下面看一個2層B+樹的例子:

注意:一般其高度都在2~3層,查詢時能夠有效減小IO次數

 系統從磁盤讀取數據到內存時是以磁盤塊(block)爲基本單位的,位於同一磁盤塊中的數據會被一次性讀取出來,而不是按需讀取。InnoDB 存儲引擎使用頁做爲數據讀取單位,頁是其磁盤管理的最小單位,默認 page 大小是 16kB。

b+樹的查找過程

  如圖所示,若是要查找數據項30,那麼首先會把磁盤塊1由磁盤加載到內存,此時發生一次IO,在內存中用二分查找肯定30在28和65之間,鎖定磁盤塊1的P2指針,內存時間由於很是短(相比磁盤的IO)能夠忽略不計,經過磁盤塊1的P2指針的磁盤地址把磁盤塊由磁盤加載到內存,發生第二次IO,30在28和35之間,鎖定當前磁盤塊的P1指針,經過指針加載磁盤塊到內存,發生第三次IO,同時內存中作二分查找找到30,結束查詢,總計三次IO。真實的狀況是,3層的b+樹能夠表示上百萬的數據,若是上百萬的數據查找只須要三次IO,性能提升將是巨大的,若是沒有索引,每一個數據項都要發生一次IO,那麼總共須要百萬次的IO,顯然成本很是很是高。

 強烈注意: 索引字段要儘可能的小,磁盤塊能夠存儲更多的索引.

 2. HASH 索引

    hash就是一種(key=>value)形式的鍵值對,容許多個key對應相同的value,但不容許一個key對應多個value,爲某一列或幾列創建hash索引,就會利用這一列或幾列的值經過必定的算法計算出一個hash值,對應一行或幾行數據.   hash索引能夠一次定位,不須要像樹形索引那樣逐層查找,所以具備極高的效率.

 

HASH與BTREE比較:


hash類型的索引:查詢單條快,範圍查詢慢
btree類型的索引:b+樹,層數越多,數據量越大,範圍查詢和隨機查詢快(innodb默認索引類型)

不一樣的存儲引擎支持的索引類型也不同
InnoDB 支持事務,支持行級別鎖定,支持 Btree、Hash 等索引,不支持Full-text 索引;
MyISAM 不支持事務,支持表級別鎖定,支持 Btree、Full-text 等索引,不支持 Hash 索引;
Memory 不支持事務,支持表級別鎖定,支持 Btree、Hash 等索引,不支持 Full-text 索引;
NDB 支持事務,支持行級別鎖定,支持 Hash 索引,不支持 Btree、Full-text 等索引;
Archive 不支持事務,支持表級別鎖定,不支持 Btree、Hash、Full-text 等索引;

 

3 索引類型:

一.普通索引

普通索引僅有一個功能:加速查詢

1 建立表同時給name字段設置爲普通索引.

2 單獨給表指定普通索引.

 

3 刪除索引

drop index idx_name on tb1;

4 查看索引

show index from tb1;

5 查看索引 列介紹


一、Table 表的名稱。

二、 Non_unique 若是索引爲惟一索引,則爲0,若是能夠則爲1。

三、 Key_name 索引的名稱

四、 Seq_in_index 索引中的列序列號,從1開始。

五、 Column_name 列名稱。

六、 Collation 列以什麼方式存儲在索引中。在MySQL中,有值‘A’(升序)或NULL(無分類)。

七、Cardinality 索引中惟一值的數目的估計值。

八、Sub_part 若是列只是被部分地編入索引,則爲被編入索引的字符的數目。若是整列被編入索引,則爲NULL。

九、 Packed 指示關鍵字如何被壓縮。若是沒有被壓縮,則爲NULL。

十、 Null 若是列含有NULL,則含有YES。若是沒有,則該列含有NO。

十一、 Index_type 用過的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

十二、 Comment 多種評註

 

二:惟一索引

惟一索引有兩個功能:加速查詢 和 惟一約束(可含一個null 值)

建立表加惟一索引

建立惟一索引

create unique index idx_age on tb2(age);

三.主鍵索引

 主鍵有兩個功能:加速查詢 和 惟一約束(不可含null)

 注意:一個表中最多隻能有一個主鍵索引.

建立表和建立兩種方式:

二:建立主鍵

alter table tb3 add primary key(id);

三:刪除主鍵

四:組合索引

 

舉個例子來講,好比你在爲某商場作一個會員卡的系統。

這個系統有一個會員表
有下列字段:
會員編號 INT
會員姓名 VARCHAR(10)
會員身份證號碼 VARCHAR(18)
會員電話 VARCHAR(10)
會員住址 VARCHAR(50)
會員備註信息 TEXT

那麼這個 會員編號,做爲主鍵,使用 PRIMARY
會員姓名 若是要建索引的話,那麼就是普通的 INDEX
會員身份證號碼 若是要建索引的話,那麼能夠選擇 UNIQUE (惟一的,不容許重複)

 

 

 

4.聚合索引和輔助索引 

數據庫中的B+樹索引能夠分爲彙集索引和輔助索引.

彙集索引:InnoDB表 索引組織表,即表中數據按主鍵B+樹存放,葉子節點直接存放整條數據,每張表只能有一個彙集索引。

如圖:

1.當你定義一個主鍵時,InnnodDB存儲引擎則把它當作彙集索引

2.若是你沒有定義一個主鍵,則InnoDB定位到第一個惟一索引,且該索引的全部列值均飛空的,則將其當作彙集索引。

3若是表沒有主鍵或合適的惟一索引INNODB會產生一個隱藏的行ID值6字節的行ID彙集索引,

補充:因爲實際的數據頁只能按照一顆B+樹進行排序,所以每張表只能有一個彙集索引,彙集索引對於主鍵的排序和範圍查找很是有利.

輔助索引:(也稱非彙集索引)是指葉節點不包含行的所有數據,葉節點除了包含鍵值以外,還包含一個書籤鏈接,經過該書籤再去找相應的行數據。下圖顯示了

InnoDB存儲引擎輔助索引得到數據的查找方式:

從上圖中能夠看出,輔助索引葉節點存放的是主鍵值,得到主鍵值後,再從彙集索引中查找整行數據。舉個例子,若是在一顆高度爲3的輔助索引中查找數據,首先從輔助索引中得到主鍵值(3次IO),接着從高度爲3的彙集索引中查找以得到整行數據(3次IO),總共需6次IO。一個表上能夠存在多個輔助索引。

總結兩者區別:

  相同的是:不論是彙集索引仍是輔助索引,其內部都是B+樹的形式,即高度是平衡的,葉子結點存放着全部的數據。

  不一樣的是:彙集索引葉子結點存放的是一整行的信息,而輔助索引葉子結點存放的是單個索引列信息.

總結兩者區別:

  相同的是:不論是彙集索引仍是輔助索引,其內部都是B+樹的形式,即高度是平衡的,葉子結點存放着全部的數據。

  不一樣的是:彙集索引葉子結點存放的是一整行的信息,而輔助索引葉子結點存放的是單個索引列信息.

什麼時候使用匯集索引或非彙集索引

下面的表總結了什麼時候使用匯集索引或非彙集索引(很重要):

動做描述

使用匯集索引

使用非彙集索引

列常常被分組排序

返回某範圍內的數據

不該

一個或極少不一樣值

不該

不該

頻繁更新的列

不該

外鍵列

主鍵列

頻繁修改索引列

不該

 

也就是總結一句話:
拿數字舉例子:好比我想找16這個數,彙集索引先先找第一層 5-28之間,選出5右邊  28左邊數據,在第二層一個範圍15 ,18 ,再在第三層找16這個數.     非彙集索引的話就是也經過b+tree方法找到15這個主鍵索引,而後在在彙集索引裏面找,通過6次io操做.
若是拿具體表舉例子,就是我新建表   id   name  age  有三列數據,經過彙集索引找的是第一行裏面全部信息(id name age) 而經過輔助索引(彙集索引)
相關文章
相關標籤/搜索