Mysql MyISAM與InnoDB 表鎖行鎖以及分庫分表優化

1、 兩種存儲引擎:MyISAM與InnoDB 區別與做用

1. count運算上的區別:

由於MyISAM緩存有表meta-data(行數等),所以在作COUNT(*)時對於一個結構很好的查詢是不須要消耗多少資源的。而對於InnoDB來講,則沒有這種緩存。算法

2. 是否支持事務和崩潰後的安全恢復:

MyISAM 強調的是性能,每次查詢具備原子性,其執行數度比InnoDB類型更快,但不提供事務支持。InnoDB 提供事務支持事務,外部鍵等高級數據庫功能。 具備事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。sql

3. 是否支持外鍵:

MyISAM不支持,而InnoDB支持。數據庫

 

1. 2 MyISAM特色(5.5 版本前默認引擎)

 

  1. MyISAM:只支持表級鎖,不支持行鎖。用戶在操做myisam表時,select,update,delete,insert語句都會給表自動加鎖 (讀取時對須要讀到的全部表加鎖,寫入時則對錶加排他鎖;)緩存

  2. 不支持事務安全

  3. 不支持外鍵數據結構

  4. 不支持崩潰後的安全恢復併發

  5. 在表有讀取查詢的同時,支持往表中插入新紀錄分佈式

  6. 支持BLOB和TEXT的前500個字符索引,支持全文索引高併發

  7. 支持延遲更新索引,極大地提高了寫入性能性能

  8. 對於不會進行修改的表,支持 壓縮表 ,極大地減小了磁盤空間的佔用

 

1.2.2 表鎖與行鎖 hang鎖

 

  • 計算機(Mysql)協調多個進程或線程併發訪問某一表或某行數據的機制
  1. 表鎖: 每次操做鎖住整張表。開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的機率最高,併發度最低;

  2. 行鎖: 每次操做鎖住一行數據。開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度最高;

 

1.3 InnoDB (5.5 版本後默認引擎

 
注意:InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的。

  1. 支持行鎖,採用MVCC來支持高併發,有可能死鎖
  2. 支持事務
  3. 支持外鍵
  4. 支持崩潰後的安全恢復
    不支持全文索引

 

1.4 綜上

因此:MyISAM更適合讀密集的表,而InnoDB更適合寫密集的的表。 在數據庫作主從分離的狀況下,常常選擇MyISAM做爲主庫的存儲引擎。
若是須要事務支持,而且有較高的併發讀取頻率(MyISAM的表鎖的粒度太大,因此當該表寫併發量較高時,要等待的查詢就會不少了),這時選InnoDB是不錯的。若是你的數據量很大(MyISAM支持壓縮特性能夠減小磁盤的空間佔用),並且不須要支持事務時,MyISAM是最好的選擇。

 

2、兩種數據結構的索引

 

哈希索引:

底層的數據結構是哈希表,所以在絕大多數需求爲單條記錄查詢的時候,能夠選擇哈希索引,查詢性能最快;其他大部分場景,建議選擇BTree索引。

B-Tree索引:下圖爲B+Tree

  1. MyISAM: B+Tree葉節點的data域存放的是數據記錄的地址。在索引檢索的時候,首先按照B+Tree搜索算法搜索索引,若是指定的Key存在,則取出其 data 域的值,而後以 data 域的值爲地址讀取相應的數據記錄。這被稱爲「非聚簇索引」。

  2. InnoDB: 其數據文件自己就是索引文件。相比MyISAM,索引文件和數據文件是分離的,其表數據文件自己就是按B+Tree組織的一個索引結構,樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,所以InnoDB表數據文件自己就是主索引。這被稱爲「聚簇索引(或彙集索引)」。而其他的索引都做爲輔助索引(非彙集索引),輔助索引的data域存儲相應記錄主鍵的值而不是地址,這也是和MyISAM不一樣的地方。在根據主索引搜索時,直接找到key所在的節點便可取出數據;在根據輔助索引查找時,則須要先取出主鍵的值,在走一遍主索引。 所以,在設計表的時候,不建議使用過長的字段做爲主鍵,也不建議使用非單調的字段做爲主鍵,這樣會形成主索引頻繁分裂。

 

3、數據庫常見優化手段

 
當MySQL單表記錄數過大時,數據庫的CRUD性能會明顯降低
增長(Create)、讀取查詢(Retrieve)、更新(Update)和刪除(Delete)

  1. 限定數據的範圍: 務必禁止不帶任何限制數據範圍條件的查詢語句。好比:咱們當用戶在查詢訂單歷史的時候,咱們能夠控制在一個月的範圍內。;

  2. 讀/寫分離: 經典的數據庫拆分方案,主庫負責寫,從庫負責讀;

  3. 緩存: 使用MySQL的緩存,另外對重量級、更新少的數據能夠考慮使用應用級別的緩存;

  4. 垂直分區:
    根據數據庫裏面數據表的相關性進行拆分。 例如,用戶表中既有用戶的登陸信息又有用戶的基本信息,能夠將用戶表拆分紅兩個單獨的表,甚至放到單獨的庫作分庫。
    簡單來講垂直拆分是指數據表列的拆分,把一張列比較多的表拆分爲多張表

  • 垂直拆分的優勢:
    可使得行數據變小,在查詢時減小讀取的Block數,減小I/O次數。此外,垂直分區能夠簡化表的結構,易於維護。

  • 垂直拆分的缺點:
    主鍵會出現冗餘,須要管理冗餘列,並會引發Join操做,能夠經過在應用層進行Join來解決。此外,垂直分區會讓事務變得更加複雜;

  1. 水平分區:
     
    保持數據表結構不變,經過某種策略存儲數據分片。這樣每一片數據分散到不一樣的表或者庫中,達到了分佈式的目的。 水平拆分能夠支撐很是大的數據量。
     
    水平拆分是指數據錶行的拆分,表的行數超過200萬行時,就會變慢,這時能夠把一張的表的數據拆成多張表來存放。

水品拆分能夠支持很是大的數據量。須要注意的一點是:分表僅僅是解決了單一表數據過大的問題,但因爲表的數據仍是在同一臺機器上,其實對於提高MySQL併發能力沒有什麼意義,因此 水品拆分最好分庫 。 水平拆分可以 支持很是大的數據量存儲,應用端改造也少,但 分片事務難以解決 ,跨界點Join性能較差,邏輯複雜。

相關文章
相關標籤/搜索