InnoDB和 MyISAM的區別

2021-09-28 23:53:04 字數 3255 閱讀 2515

myisam 和innodb

情景一:

在寫多讀少的情況下選擇哪乙個?

innodb。它的插入效能比較好,對於併發事務的處理較好。

分析總結所適用場景:

主鍵盡可能小,避免給secondary index帶來過大的空間負擔

避免全表掃瞄,因為會使用表鎖

盡可能快取所有的索引和資料,提高響應速度

在大批量小插入的時候,盡量自己控制事務而不要使用autocommit自動提交

合理設定innodb_flush_log_at_trx_commit引數值,不要過度追求安全性

避免主鍵更新,因為這會帶來大量的資料移動

情景二:

如果對讀取速度要求比較高如何選?

myism。

分析總結所使用場景:

盡量索引(快取機制)

調整讀寫優先順序,根據實際需求確保重要操作更優先

啟用延遲插入改善大批量寫入效能

盡量順序操作讓insert資料都寫入到尾部,減少阻塞

分解大的操作,降低單個操作的阻塞時間

降低併發數,某些高併發場景通過應用來進行排隊機制

對於相對靜態的資料,充分利用query cache可以極大的提高訪問效率

myisam的count只有在全表掃瞄的時候特別高效,帶有其他條件的count都需要進行實際的資料訪問

下面給出了詳細的分析:

1、myisam不支援事務,innodb是事務型別的儲存引擎,當我們的表需要用到事務支援的時候,

那肯定是不能選擇myisam了。

2、myisam只支援表級鎖,bdb支援頁級鎖和表級鎖預設為頁級鎖,

而innodb支援行級鎖和表級鎖預設為行級鎖

表級鎖:

直接鎖定整張表,在鎖定期間,其他程序無法對該錶進行寫操作,

如果設定的是寫鎖,那麼其他程序讀也不允許 myisam是表級鎖定的儲存引擎,它不會出現死鎖問題 對於write,

表鎖定原理如下:

如果表上沒有鎖,在其上面放置乙個寫鎖,否則,把鎖定請求放在寫鎖佇列中。

對於read,表鎖定原理如下 :

如果表上沒有寫鎖定,那麼把乙個讀鎖放在其上面,否則把鎖請求放在讀鎖定佇列中

當乙個鎖定被釋放時,錶可被寫鎖定佇列中的執行緒得到,然後才是讀鎖定佇列中的執行緒。

這意味著,如果你在乙個表上有許多更新,那麼你的select語句將等到所有的寫鎖定執行緒執行完。

行級鎖:

只對指定的行進行鎖定,其他程序還是可以對錶中的其他行進行操作的。

行級鎖是mysql粒度最小的一種鎖,它能大大的減少資料庫操作的衝突,但是粒度越小實現成本也越大。

行級鎖可能會導致「死鎖」,

那到底是怎麼導致的呢?

分析原因:

mysql行級鎖並不是直接鎖記錄,而是鎖索引。

索引分為主鍵索引和非主鍵索引兩種,如果一條sql語句操作了主鍵索引,

那麼mysql就會鎖定這個主鍵索引,如果sql語句操作的是非主鍵索引,

那麼mysql會先鎖定這個非主鍵索引,再去鎖定主鍵索引。

在update 和 delete操作時mysql不僅會鎖定所有where 條件掃瞄過得索引,還會鎖定相鄰的鍵值。

「死鎖」舉例分析:

表test:(id,state,time)

主鍵索引:id

非主鍵索引:

state 當執行"update state =1011 where state=1000" 語句的時候會鎖定state索引,

由於state 是非主鍵索引,所以mysql還會去請求鎖定id索引

當另乙個sql語句與語句1幾乎同時執行時:「update state=1010 where id=1」

對於語句2

mysql會先鎖定id索引,由於語句2操作了state欄位,所以mysql還會請求鎖定state索引。

這時。彼此鎖定著對方需要的索引,又都在等待對方釋放鎖定。所以出現了"死鎖"的情況。

行級鎖的優點:

有許多執行緒訪問不同的行時,只存在少量的衝突。 回滾時只有少量的更改 可以長時間鎖定單一的行

行級鎖缺點:

相對於頁級鎖和表級鎖來說占用了更多的記憶體 當表的大部分行在使用時,

比頁級鎖和表級鎖慢,因為你必須獲得更多的鎖 當在大部分資料上經常使用group by操作,

肯定會比表級鎖和頁級鎖慢。

頁級鎖:

表級鎖速度快,但是衝突多;行級鎖速度慢,但衝突少;頁級鎖就是他倆折中的,

一次鎖定相鄰的一組記錄。

3、myisam引擎不支援外來鍵,innodb支援外來鍵

4、myisam引擎的表在大量高併發的讀寫下會經常出現表損壞的情況

我們以前做的專案就遇到這個問題,表的insert 和 update操作很頻繁,

原來用的myisam引擎,導致表隔三差五就損壞,後來更換成了innodb引擎。

其他容易導致表損壞原因: 伺服器突然斷電導致資料檔案損壞,

強制關機(mysqld未關閉情況下)導致表損壞 mysqld程序在寫入操作的時候被殺掉 磁碟故障

表損壞常見症狀:

查詢表不能返回資料或返回部分資料 開啟表失敗:

can』t open file: 『×××.myi』 (errno: 145) 。

error: table 'p' is marked as crashed and should be repaired 。

incorrect key file for table: '...'. try to repair it mysql表的恢復:

對於myisam表的恢復:

可以使用mysql自帶的myisamchk工具:

myisamchk -r tablename 或者 myisamchk -o tablename(比前面的更保險) 對錶進行修復

5、對於count()查詢來說myisam更有優勢因為myisam儲存了表中的行數記錄,

執行select count() 的時候可以直接獲取到結果,而innodb需要掃瞄全部資料後得到結果。

但是注意一點:

對於帶有where 條件的 select count()語句兩種引擎的表執行過程是一樣的,

都需要掃瞄全部資料後得到結果

6、 innodb是為處理巨大資料量時的最大效能設計,

它的cpu效率可能是任何其它基於磁碟的關聯式資料庫引擎所不能匹敵的。

7、myisam支援全文索引(fulltext),innodb不支援

8、myisam引擎的表的查詢、更新、插入的效率要比innodb高

MySQL中MyISAM與InnoDB區別

mysql中myisam與innodb區別 myisam innodb 事物處理 不支援支援 外來鍵不支援 支援行鎖 不支援支援 全文索引 支援不支援 表的具體行數 儲存表的具體行數 掃瞄表來計算行數 delete表時 先drop表,然後重建表 一行一行的刪除 索引和資料 分開的,並且索引是有壓縮的...

MySQL中MyISAM與InnoDB區別及選擇

innodb 支援事務處理等 不加鎖讀取 支援外來鍵 支援行鎖 不支援fulltext型別的索引 不儲存表的具體行數,掃瞄表來計算有多少行 delete 表時,是一行一行的刪除 innodb 把資料和索引存放在表空間裡面 跨平台可直接拷貝使用 innodb中必須包含auto increment型別欄...

MySQL中MyISAM與InnoDB區別及選擇

支援事務處理等 不加鎖讀取 支援外來鍵 支援行鎖 不支援fulltext型別的索引 不儲存表的具體行數,掃瞄表來計算有多少行 delete 表時,是一行一行的刪除 innodb 把資料和索引存放在表空間裡面 跨平台可直接拷貝使用 innodb中必須包含auto increment型別欄位的索引 很難...