索引差別
- MyISAM不管是主鍵索引,唯一鍵索引,或者普通索引,都是屬于稀疏索引。
- InnoDB必須有且僅有一個密集索引,這個密集索引的選取規則如下:
- 若一個主鍵被定義,該主鍵則作為密集索引;
- 若沒有主鍵被定義,将表的第一個唯一非空索引則作為密集索引;
- 若不滿足以上條件,InnoDB内部會生成一個隐藏主鍵(密集索引),這個隐藏的主鍵是一個6位元組的列,該列的值會随着資料的插入而自增,也就是說,我們的InnoDB必須有一個主鍵,而該主鍵就必須作為唯一的密集索引而存在。
InnoDB必須有一個主鍵
非主鍵索引(稀疏索引)的葉子節點并不存儲行資料的實體位址,而是存儲該行的主鍵值,是以非主鍵索引包含了兩次查找,一次是查找次級索引,然後再查找主鍵
索引過程
InnoDB:使用的是密集索引,将主鍵組織到一顆B+樹中,而行資料就存儲在葉子節點上,因為InnoDB的主鍵索引和對應的資料是儲存在同一個檔案當中的。是以檢索的時候,在加載葉子節點的主鍵進入記憶體的同時加載了對應的資料。
- 主鍵查詢:若使用"where id = 1"這樣的條件查詢主鍵,就可以按照B+樹的檢索算法查找到對應的葉子節和它對應的行資料。
- 條件查詢:若對稀疏索引進行條件篩選,則需要經曆兩個步驟
- 在稀疏索引的B+樹中檢索name=“Alex”,找出該資料對應的主鍵
- 使用主鍵"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鎖