聚集和非聚集索引
簡單概括:
- 聚集索引就是以主鍵創建的索引
- 非聚集索引就是以非主鍵創建的索引
區別:
- 聚集索引在葉子節點存儲的是表中的數據
- 非聚集索引在葉子節點存儲的是主鍵和索引列
- 使用非聚集索引查詢出數據時,拿到葉子上的主鍵再去查到想要查找的數據。(拿到主鍵再查找這個過程叫做回表)
非聚集索引也叫做二級索引,不用糾結那么多名詞,將其等價就行了~
非聚集索引在建立的時候也未必是單列的,可以多個列來創建索引。
- 此時就涉及到了哪個列會走索引,哪個列不走索引的問題了(最左匹配原則-->后面有說)
- 創建多個單列(非聚集)索引的時候,會生成多個索引樹(所以過多創建索引會占用磁盤空間
創建多列索引中也涉及到了一種特殊的索引-->覆蓋索引
- 我們前面知道了,如果不是聚集索引,葉子節點存儲的是主鍵+列值
- 最終還是要“回表”,也就是要通過主鍵再查找一次。這樣就會比較慢
- 覆蓋索引就是把要查詢出的列和索引是對應的,不做回表操作!
比如說:
- 現在我創建了索引
(username,age)
,在查詢數據的時候:select username , age from user where username = 'Java3y' and age = 20
。 - 很明顯地知道,我們上邊的查詢是走索引的,並且,要查詢出的列在葉子節點都存在!所以,就不用回表了~
- 所以,能使用覆蓋索引就盡量使用吧~
存儲特點
- 聚集索引。表數據按照索引的順序來存儲的,也就是說索引項的順序與表中記錄的物理順序一致。對於聚集索引,葉子結點即存儲了真實的數據行,不再有另外單獨的數據頁。 在一張表上最多只能創建一個聚集索引,因為真實數據的物理順序只能有一種。
- 非聚集索引。表數據存儲順序與索引順序無關。對於非聚集索引,葉結點包含索引字段值及指向數據頁數據行的邏輯指針,其行數量與數據表行數據量一致。
總結一下:聚集索引是一種稀疏索引,數據頁上一級的索引頁存儲的是頁指針,而不是行指針。而對於非聚集索引,則是密集索引,在數據頁的上一級索引頁它為每一個數據行存儲一條索引記錄。
innodb可重復讀隔離級別解決國不可重復讀在問題,利用MVCC版本解決的。
innode利用next-key locks間隙鎖解決的是當前讀情況下的幻讀。
臟讀和不可重復讀都是一個事務讀,另外一個事務寫引起的。
而兩個事務一起寫造成讀寫沖突時,造成丟失更新:一個事務的更新覆蓋了其它事務的更新結果。解決的辦法有:
- 使用Serializable隔離級別,事務是串行執行的!
- 樂觀鎖
- 悲觀鎖
如果我們的鎖用到索引就是行鎖,如果沒有用到索引就是表鎖,但是我們操作的數據必須用到鎖才行。
注意幾點:
1.行鎖必須有索引才能實現,否則會自動鎖全表,那么就不是行鎖了。
2.兩個事務不能鎖同一個索引