天天看點

MySQL主要的兩種存儲引擎:MyISAM、InnoDB比較

索引差別

  • MyISAM不管是主鍵索引,唯一鍵索引,或者普通索引,都是屬于稀疏索引。
  • InnoDB必須有且僅有一個密集索引,這個密集索引的選取規則如下:
    1. 若一個主鍵被定義,該主鍵則作為密集索引;
    2. 若沒有主鍵被定義,将表的第一個唯一非空索引則作為密集索引;
    3. 若不滿足以上條件,InnoDB内部會生成一個隐藏主鍵(密集索引),這個隐藏的主鍵是一個6位元組的列,該列的值會随着資料的插入而自增,也就是說,我們的InnoDB必須有一個主鍵,而該主鍵就必須作為唯一的密集索引而存在。

InnoDB必須有一個主鍵

非主鍵索引(稀疏索引)的葉子節點并不存儲行資料的實體位址,而是存儲該行的主鍵值,是以非主鍵索引包含了兩次查找,一次是查找次級索引,然後再查找主鍵

索引過程

InnoDB:使用的是密集索引,将主鍵組織到一顆B+樹中,而行資料就存儲在葉子節點上,因為InnoDB的主鍵索引和對應的資料是儲存在同一個檔案當中的。是以檢索的時候,在加載葉子節點的主鍵進入記憶體的同時加載了對應的資料。

  • 主鍵查詢:若使用"where id = 1"這樣的條件查詢主鍵,就可以按照B+樹的檢索算法查找到對應的葉子節和它對應的行資料。
  • 條件查詢:若對稀疏索引進行條件篩選,則需要經曆兩個步驟
    1. 在稀疏索引的B+樹中檢索name=“Alex”,找出該資料對應的主鍵
    2. 使用主鍵"where id = 1"在密集索引的**B+**樹中再執行一次檢索操作,最終再到達葉子節點,擷取對應的行資料。

MyISAM:使用的是稀疏索引,稀疏索引的兩顆**B+樹,節點的結構是一緻的,隻是存儲的内容不一樣而已。主鍵索引B+樹的節點存儲了主鍵,輔助鍵索引B+樹的節點存儲的是輔助鍵,表資料是單獨存儲在獨立的地方。這兩顆B+**樹的葉子節點都使用一個位址指向真正的資料。

對于表資料來說,這兩個鍵沒有任何差别,由于索引樹是獨立。MyISAM相比于InnoDB,通過輔助鍵檢索,無需通路主鍵的索引樹。

MyISAM與InnoDB關于鎖方面的差別

  • MyISAM預設表級鎖,不支援行級鎖
    • 查詢時,會給整個表上讀鎖(共享鎖)
    • 增删改時,會給整個表上寫鎖(派它鎖)。

      存在讀鎖時,另一個session做讀操作 不會 被阻塞

      存在讀鎖時,另一個session做寫操作 會 被阻塞

      存在寫鎖時,另一個session做讀操作 會 被阻塞

      存在寫鎖時,另一個session做寫操作 會 被阻塞

  • InnoDB預設行級鎖,支援表級鎖
    • sql沒有用到索引時,用的是表級鎖。
    • sql用到索引時,用到行級鎖和gap鎖

标級鎖與索引無關

行級鎖與索引有關:sql用到了索引,涉及到的行都會被上共享鎖或者排它鎖

MyISAM InnoDB
場景

頻繁執行全表count語句:用一個變量儲存整個表的行數對

資料進行增删改頻率不高時,查詢非常頻繁

無事務

增删改查都非常頻繁

可靠性比較高,要求支援事務

RR級别:通過引入next-key鎖來避免幻讀問題

next-key由Record lock和Gap lock組成

Gap lock會用在非唯一索引或不走索引的目前讀,以及僅命中部分條件的部分結果集,并且是用到主鍵索引和唯一索引的目前讀中

RC已送出讀 RR可重複讀 級别下的InnoDB的非阻塞讀

  • 資料行裡的DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID字段
    • DB_TRX_ID:辨別最後一次對本行做修改的事務辨別符
    • DB_ROLL_PTR:復原指針
    • DB_ROW_ID:行号
  • undo日志:對資料進行變更操作時就會産生undo記錄,存儲老版資料
  • read view:可見性判斷

對主鍵索引或者唯一索引會用Gap鎖嗎

  • 如果where條件全部命中,則不會用Gap鎖,隻會加記錄鎖Record lock
  • 如果where條件部分命中或者全都不命中,則會加Gap鎖