深入淺出分析MySQL MyISAM與INNODB索引原理、優缺點分析


本文淺顯的分析了MySQL索引的原理及針對主程面試的一些問題,對各種資料進行了分析總結,分享給大家,希望祝大家早上走上屬於自己的"成金之路"。

學習知識最好的方式是帶着問題去研究所獲取的資料,分析所獲取資料的優點和不足,然后歸納匯總資料,結合使用場景形成整體的知識脈絡體系,本文行文依據各類問題展開,並附上具體的資料,引導大家走上屬於自己的"成金之路"。

目錄:

1.索引有哪幾種?各種索引優缺點?
2.索引的結構及為什么使用這種結構?
3.INNODB表索引常見面試問題——"最左綴"及ID自增問題

1.索引有哪幾種?各種索引優缺點?

提及索引,第一個問題應該是索引有哪幾種,各種索引有啥優缺點,針對這個問題去搜索資料,較全面及優質的資料見http://www.2cto.com/database/201501/368126.html;這里做一個簡單匯總:

  • 按表類型分為:MyISAM表索引與INNODB表索引;按索引特征又分為唯一索引與全文索引、單列索引與多列索引、聚簇索引。

  • MyISAM表索引與INNODB表索引區別:

  1. 聚簇索引指索引中鍵值與表數據存儲在一起,這里主要是INNODB表索引,顯然索引與數據存在一起的好處就是數據獲取效率高。
  2. 而MyISAM表索引與表數據是分開存儲的,索引保存在"表名.MYI"文件內,而數據保存在"表名.MYD"文件內;
  • 其它注意點
  1. 另外一個重要的區別是MyISAM表不支持事務,INNODB表在每行數據中增加了DB_TRX_ID、db_roll_ptr、db_row_id三個值來支持事務。
  2. 唯一索引強調索引值必須唯一,比如主鍵;全文索引一般在CHAR、VARCHAR或TEXT列上創建,MyISAM表支持而INNODB表不支持,常見主要針對文本進行索引。
  3. 典型的應用場景區分:MyISAM表索引在處理文本索引時更具優勢,而INNODB表索引在其它類型上更具效率優勢,同時MySQL高並發需要事務場景時,只能使用INNODB表。

2.索引的結構及為什么使用這種結構?

  • 索引的結構大家都都知道是B+Tree,那么第一個問題就是為什么要使用這種Tree,而不是RB-Tree?

這點從磁盤讀寫上給出解釋,磁盤順序讀寫時才能達到其宣傳的數值(fio可以進行簡單的讀寫測試),因為隨機讀寫,機械磁盤需要旋轉及尋道時間,哪怕是ssd,隨機讀寫也需要尋址時間;那么如果將索引tree構建的層數越低,使得key相近的數據都存在一起,伴隨磁盤預讀特性,能更進一步提高性能。
那么使用B+Tree的關鍵就是Tree層數低(3層),有序的數據存儲位置接近,結合磁盤順序讀寫、OS預讀寫特性,使得能很快定位到數據;而使用RB-Tree時key值相近的數據會存儲的較遠,導致效率低下。

  • 另外的一個問題就是數據插入時,怎么來平衡樹,詳見http://taop.marchtea.com/03.02.html。
  • 同時就是為了提高存儲效率,盡量較少進行Tree的平衡操作,通過讓key盡量保持自增,這樣新增的數據即可按順序進行存儲,而不會或少量對已經存儲的數據進行變更。

3.INNODB表索引"最左綴"及ID自增問題

  • "最左綴"問題即創建聯合索引(a,b,c)的使用問題?
  1. 首先要明白多列索引與聯合索引區別
    參見http://www.infocool.net/kb/Mysql/201603/26364.html以文件字節進行了分析。
  1. 多個單列索引一個索引一棵樹:

MyISAM聯合索引時,因為Tree存儲的是地址,故每個索引都能追蹤到表數據地址;
InnoDB表數據和索引一起構成B+Tree,這里假設a為Primary Key,InnoDB表數據與按Primary Key構成B+Tree,然后創建b(second-key)、c(third-key)時,根據的b、c兩列的數據作為key構建索引,而索引中存儲的數據為Primary-Key值,查詢時先檢查輔助索引獲得Primary-Key,然后再根據Primary-Key獲取數據
故InnoDB主鍵建議為單調,且不宜過長。

  • 多列組成聯合索引一棵樹:

假設a為主鍵,則以a先放,a相同的情況下按b的順序放,然后b相同按照c的順序放。
那么"最左綴"問題就很容易解釋清楚了,像(b,c)/(c)/(a,c),因為無法按照索引樹的規則來進行索引,導致需要全局掃描;而(a)/(a,b)/(a,b,c)則能使用到索引。
另外針對(a,c)如果b列的數據都是重復數據,比如星期數據,則可以將(a,c)轉為(a,b in (monday, ..., sunday),c)進行索引。
查詢優化問題詳見http://blog.codinglabs.org/articles/theory-of-mysql-index.html優化部分。

ID自增問題

顯然INNODB表索引需要ID自增效率更好,而為了保證高並發下安全,采取鎖表,進行ID的自增,詳見http://www.cnblogs.com/zhoujinyi/p/3433823.html;另外鎖表效率在超高並發下,肯定效率會受到影響,那么引入"預申請"機制來提高效率,即為每次不定的操作多申請幾個ID,保證效率,但會導致不連續。

希望祝大家早上走上屬於自己的"成金之路",如果覺得不錯,煩請不吝"推薦",助於傳播。謝謝,轉載請注明出處(百度搜 成金之路)。
也可將我沒有涉及到的問題進行留言,然后我去搜集資料、整理更新。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM