1.MySQL存儲引擎及區別
特性 | MyISAM | Memory | InnoDB |
---|---|---|---|
B+ 樹索引 | ? Yes | ? Yes | ? Yes |
備份 / 按時間點恢復 | ? Yes | ? Yes | ? Yes |
集群數據庫支持 | ? No | ? No | ? No |
聚簇索引 | ? No | ? No | ? Yes |
壓縮數據 | ? Yes | ? No | ? Yes |
數據緩存 | ? No | N/A | ? Yes |
加密數據 | ? Yes | ? Yes | ? Yes |
外鍵支持 | ? No | ? No | ? Yes |
全文檢索 | ? Yes | ? No | ? Yes |
地理空間數據類型支持 | ? Yes | ? No | ? Yes |
地理空間索引支持 | ? Yes | ? No | ? Yes |
哈希索引 | ? No | ? Yes | ? No |
索引緩存 | ? Yes | N/A | ? Yes |
鎖的粒度 | Table | Table | Row |
MVCC | ? No | ? No | ? Yes |
復制支持 | ? Yes | Limited | ? Yes |
存儲限制 | 256 TB | RAM | 64 TB |
T-tree 索引 | ? No | ? No | ? No |
事務 | ? No | ? No | ? Yes |
存儲引擎 | 特點 | 事務支持 | 鎖粒度 | 適用場景 | |
---|---|---|---|---|---|
InnoDB | MySQL 8.0 默認引擎,支持 ACID 事務,行級鎖,支持外鍵,支持崩潰恢復 | ? | 行鎖 | 高并發 OLTP 系統 | |
MyISAM | 不支持事務,只有表級鎖,讀取速度快,占用空間小,支持全文索引 | ? | 表鎖 | 以讀為主、日志、歸檔類系統 | |
Memory | 數據存儲在內存中,速度極快,但數據易丟失(重啟清空),支持哈希索引 | ? | 表鎖 | 臨時表、緩存計算 | |
CSV | 數據存儲為 CSV 文件,方便與外部程序交換數據,不支持索引 | ? | 表鎖 | 數據導入導出 |
2.Mysql的InnoDB引擎中的聚簇索引和非聚簇索引有什么區別?
聚簇索引的非葉子節點存儲的是索引值,葉子節點存儲的是完整的數據記錄,一個表只能有一個聚簇索引,一般是表的主鍵,主要用于范圍查詢和排序。非聚簇索引的非葉子節點存儲的也是索引值,但是葉子節點存儲的是數據行的主鍵和對應的索引列,一個表可以有多個非聚簇索引,非聚簇索引又稱為助索引,二級索引等,主要用于快速定位 要查找的列。
補充回答
聚簇索引簡單理解就是把索引和數據記錄放在一起了,通過索引就可以直接找到數據行了,而非聚簇索引,還需要通過回表找到相應的數據記錄。擴展回答 (引導思路及面試假想)
擴展回答
1:為什么聚簇索引查詢速度快?
在lnnoDB中,聚簇索引指的是按照每張表的主鍵構建的一種索引方式,它是將表數據按照主鍵的順序存儲在磁盤上的一種方式。這種索引方式保證了行的物理存儲順序與主鍵的邏輯順序相同,因此查找聚簇索引的速度非常快。
2:沒有創建主鍵怎么辦?
其實數據庫記錄中除了我們自己定義的字段外,還會添加一些隱藏字段,比如db_row_id,如果我們沒有創建主鍵,會默認選擇一個唯一索引作為聚簇索引,如果唯一索引也沒有,默認就選擇隱藏主鍵db_row_id作為聚簇索引l。
3:上面提到的回表是什么意思?
通常我們使用聚簇索就可以直接查找到數據記錄,但是非聚簇索引由于它的葉子節點只存儲主鍵值和索引值,這種情況下我們使用非聚簇索引查詢相應的數據記錄,需要先查到對應的葉子節點的主鍵值,然后再用主鍵值進行一次查詢才能獲得我們需要的數據記錄,這個過程稱為回表。
4:為什么主鍵查詢效率快?
從上面的回答可以看出,主鍵索引查詢數據記錄不需要回表,減少了查詢步驟,相應也提升的查詢效率。
5:我們應該如何提升查詢效率呢?
前面我們說到回表會降低查詢效率,所以我們應該通過優化索引結構,添加相應的索引以及優化sql語句,減少回表的次數以提升查詢的效率,同時我們也可以依賴覆蓋索引、索引下推等技術。
6:既然你提到了索引下推,和索引覆蓋,能否具體講一下?
索引覆蓋就是在索引中就包含了我們需要查詢的數據列,比如我想查詢column2,此時有一個索引記錄(columnl,column2),那我們通過索引columnl進行查詢 select column2 from table where column1='test’,上面的情況就是覆蓋索引的例子,這種情況就不需要回表進行查詢了。接下來講下索引下推,這個也很好理解,首先我們需要了解,存儲引擎只能根據索引例的值來定位到對應勺主鍵值,然后回表獲取完整的記錄行。如果查詢條中還有其他未在索引中使用的篩選條件,那么這些條件只能在回表獲取完整行之后在服務器層進行判斤。這就導致了很多不滿足條件的記錄也進行了回表桑作,增加了回表的次數。為了減少回表次數,我們可以利用索引下推技術在存儲引擎層使用索引中的列來進行額外的篩選操作,而不僅僅是使用索引來定位已錄的主鍵值。總結來說就是,索引下推就是聯合索在本身數據就有的情況下,直接通過聯合索引再進行一次數據的過濾,而不是通過回表返回到server層行數據的過濾。
3. MySQL 索引類型
按數據結構分類:
- B+Tree 索引(最常用,支持范圍查詢、排序)
- Hash 索引(Memory 引擎支持,等值查詢快,不支持范圍查詢)
- R-Tree 索引(空間索引,MyISAM 的 GIS 數據)
- Fulltext 索引(全文搜索,MyISAM/InnoDB 支持)
按功能分類:
- 主鍵索引(Primary Key)
- 唯一索引(Unique Key)
- 普通索引(Index)
- 全文索引(Fulltext)
- 空間索引(Spatial)
按物理存儲分類:
- 聚簇索引(Clustered Index)
- 非聚簇索引(Secondary Index / 非主鍵索引)
- 覆蓋索引(Covering Index,索引包含查詢所需的所有列,無需回表)
- 組合索引(Composite Index,多列聯合索引)
- 前綴索引(Prefix Index,對字符串前 N 個字符建索引)
拓展:
1.InnoDB為什么使用B+樹實現索引?
1.B+樹是一棵平衡樹,每個葉子節點到根節點的路徑長度相同,查詢效率高
2.所有關鍵字都在葉子節點上,因此范圍查詢時只需要謠歷一遍葉子節點即可。
3.葉子節點都按照關鍵字的大小順序存放,因此可以快速的根據關鍵字大小進行排序。
4.非葉子節點不存儲實際數據,因此可以存儲更多的索引數據
5.非葉子節點適用指針鏈接葉子節點,因此可以快速的支持范國查詢和倒序查詢。
6.葉子節點之間通過 雙向鏈表鏈接,方便進行范國查詢。
所以可以總結得出,使用B+樹有以下有幾點,支持范圍查詢、支持排序、可以存儲更多的索引數據、因為葉子節點大小固定,節點分裂和合并時,IO操作少,同時因為大小固定,還有利于磁盤預讀,因為非葉子節點只存儲指向子節點的指針,而不存儲據,所以可以緩存更多的索引數據,有利于緩存。
2.B+樹索引l和Hash索引有什么區別?
1.因為B+樹索引將索引列的值按照大小排序存儲,所以更適合于范圍查詢,而哈希索引是基于Hash表的結構,所以哈希索引更適合等值查詢,但不適合范圍查詢和排序操作。
2.如果B+樹索引插入數據和刪除數據時需要調整索引結構,可能涉及到頁分裂和頁合并等操作(無序插入),維護成本較高,而哈希索引在插入和刪除數據只需要計算哈希值并插入或者刪除相應的記錄。
3.B+樹索引在磁盤上是有序存儲的,而哈希索引是無序存儲的
3.唯一索引和主鍵索引的區別?
兩者都具有唯一性,但是主鍵索引不能為null,唯一索引可以,主鍵索引每表只能有一個,唯一索引可以創建多個,在innoDB中,主鍵索引就是聚簇索引,但唯一索引通常是非聚簇索引(除了特殊情況,就是在沒有創建主鍵索引的情況下,MySQL會默認選擇一個唯一的非空索引I作為聚簇索引),同時主鍵索引一定不需要回表,但是唯一索引查詢通常是需要回表的,主鍵可以被其他表引用為外鍵,而唯一索引不可以。
4.MySQL如何保證唯一索引I的唯一性?
在支持事務的存儲引擎中(例如lnnoDB)中,事務機制和鎖定協議幫助維護索引的唯一性,當個事務正在修改索引引列時,其他事務對相同鍵值的修改會被適當的阻塞,直到第一個事務提交或回滾,確保了數據的一致性和唯一性,并且在實際的寫入數據到磁盤之前,MySQL也會執行約束檢查,確保不會違反唯一性約束。相應的因為唯一索引保證了指定列的值唯一,會讓唯一性索引查詢比非唯一性查詢根塊,因為能夠快速的匹配到唯一的記錄,但是也是因為要保證索引列的唯一性,因此在插入的時候需要檢查是否存在相同的索引值,會對插入性能產生一定的影響。