InnoDB與MyISAM該如何選擇

題目算對本文的一個概括,但我不想一上來就對這兩個MySQL引擎一頓比較。這篇博客的切入點,一切的一切都是因爲別人問了我一句:MySQL的數據結構是什麼?

聽到這個問題,腦子裏B+樹、B樹、Hash爭着往外蹦,可是沒蹦出去,因爲忽然想到,這不是索引的數據結構嗎?索引的數據結構和數據庫的數據結構是一個東西?可是數據庫本質上就是文件數據存儲當然有數據結構,索引它憑什麼有數據結構這麼一說?一連串的靈魂拷問讓索引忽然變得好抽象,我怎麼突然什麼都不確定了。

那就捋一捋吧,先糾正自己的兩個理解誤區:

誤區一:B樹、B+樹包括Hash不是說是索引的數據結構,準確的說是索引的!結構,就是索引結構嘛,貼一張索引的百度詞條:

相當於說這個目錄長的和B+樹一樣。

誤區二:數據結構的意思就是數據是怎麼放的,比如在B樹中數據直接放在節點裏,而B+樹只有葉子節點纔有數據。所以索引結構就是數據庫的數據結構,有點繞,總之數據庫的數據結構就是B樹,B+樹包括Hash這些。

在梳理這兩個理解誤區的過程中,巧了還發現自己的兩個認知誤區。都知道索引可以分好多類,按索引列是否爲主鍵可以分爲主鍵索引和普通索引,按葉子節點是否存有全部數據還是隻有數據的一個索引編碼可以分爲聚簇索引和非聚簇索引,有兩個認知誤區:

誤區一:建索引的時候可以選擇建聚簇索引還是非聚簇索引(這個其實是想當然)。

誤區二:主鍵索引就是聚簇索引,普通索引就是非聚簇索引。

反思了一下爲什麼會有這兩個誤區,可能是因爲現在MySQL默認的引擎是InnoDB,而工作中一般不涉及更換選擇其他引擎例如MyISAM,所以滿腦子都是InnoDB,什麼都是InnoDB,這樣下來肯定會有問題。其實MySQL的索引在InnoDB中只有聚簇索引,在MyISAM中只有非聚簇索引,現在想想建索引的時候好像確實沒有選擇聚簇還是非聚簇。至於主鍵索引和普通索引,在InnoDB中都會存在,因爲InnoDB中必須要有一個主鍵,哪怕不指定主鍵也默認生成一個6位的作爲主鍵,所以InnoDB中肯定有主鍵索引。而同時InnoDB中的索引都是聚簇索引,可能這導致我誤解成了前半句,後半句估計是我想當然出來的,InnoDB中也有普通索引,InnoDB中的普通索引也是聚簇索引,只有MyISAM中的普通索引纔是非聚簇索引,而且MyISAM中是允許沒有主鍵的。

說了這麼多,終於開始提到兩種引擎MyISAM和InnoDB了,那就抓住機會扣個題吧。先羅列一下這兩種引擎的區別:

1.InnoDB是行級鎖,MyISAM是表級鎖。

2.InnoDB支持外鍵,MyISAM不支持。

3.InnoDB支持事務,MyISAM不支持。

4.InnoDB屬於索引組織表,MyISAM屬於堆表。

5.InnoDB必須有主鍵,MyISAM不一定。

6.InnoDB索引都是聚簇索引,MyISAM都是非聚簇索引。

7.InnoDB不保存表的總行數,MyISAM保存着。所以count(*)的時候InnoDB要去掃描全表記錄行數,MyISAM直接拿快的很。

8.InnoDB不支持FullText全文索引,而MyISAM支持。當然InnoDB可以通過插件實現全文索引。

一下子羅列了這麼多,看看就行了,我也記不住。有一個問題可以思考一下,爲什麼MyISAM適合查詢較多的情況而InnoDB適合增刪改較多的情況。從以上羅列的8條區別中也可以找到部分答案,因爲MyISAM不支持事務,所以增刪改過多不合適。但是爲什麼MyISAM的查詢效率會實打實的比InnoDB高的,按理說MyISAM表級鎖顆粒度應該更高啊。即使說MyISAM中的索引都是非聚簇索引,葉子節點只有數據編碼,必然需要回表,如果InnoDB索引覆蓋,聚簇索引葉子節點直接就能取到數據不需要回表,這種情況下哪個快呢?我沒有去深究這個問題,去網上搜了一下爲什麼MyISAM查詢效率比InnoDB快,貼一些一致的答案:

1.select的時候InnoDB要緩存所有查詢的數據塊,而MyISAM只需要緩存索引快。

2.InnoDB尋址要先映射到塊,再映射到行,而MyISAM記錄的直接就是文件的offset,數據的定位比InnoDB快。

3.InnoDB因爲支持事務,還需要維護MVCC一致,即使查詢不涉及到事務,但是還是有一個檢查和維護MVCC的過程。可以順便提一下InnoDB是怎麼實現MVCC(多版本併發控制)的,其實就是爲每一行記錄追加兩個額外的隱藏值,一個記錄這行數據何時被創建,一個記錄這行數據何時過期,但是不是真的通過兩個時間來記錄,而是通過系統版本號的方式表示,所以這個系統版本號越來越大,這麼一來每次都要去維護這個系統版本號確實挺耗時間的。

這麼看來MyISAM的查詢效率確實比InnoDB要快不少,人家甩膀子生活沒壓力啊。

最後再扣一下題,這麼選擇這兩個引擎呢,想一想前面羅列的8點區別,再考慮一下以下幾個問題:

1.數據是否有外鍵

2.需要支持事務嗎

3.需要全文索引嗎

4.數據量大不大,大的話就用InnoDB,數據不多就用MyISAM吧,還能全文索引呢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章