文章目錄
- 1. 數據存儲方式
- 2. 索引結構
- 3. 查詢效率
- 4. 索引數量
- 5. 適用場景
- 6. 示例說明
- 7. 總結
在MySQL中,聚集索引和非聚集索引(也稱二級索引)的區別主要體現在數據存儲方式、索引結構和查詢效率等方面。以下是詳細對比:
1. 數據存儲方式
-
聚集索引
數據行的物理存儲順序與索引順序完全一致。
每個表只能有一個聚集索引,通常是主鍵。若未定義主鍵,InnoDB會隱式創建一個隱藏的ROW_ID
作為聚集索引。 -
非聚集索引
索引順序與數據行的物理存儲順序無關。
葉子節點存儲的是主鍵值(InnoDB)或數據行的物理地址(MyISAM),而非數據本身。
2. 索引結構
-
聚集索引
B+樹的葉子節點直接包含完整的數據行,因此通過聚集索引查詢時可直接獲取數據,無需額外查找。 -
非聚集索引
B+樹的葉子節點存儲主鍵值(InnoDB)或指向數據行的指針(MyISAM)。查詢時可能需要二次查找(回表),即通過主鍵值到聚集索引中獲取完整數據行。
3. 查詢效率
-
聚集索引
- 優點:范圍查詢(如
BETWEEN
、ORDER BY
)效率高,因為數據物理連續。 - 缺點:插入和更新可能引發頁分裂,影響性能。
- 優點:范圍查詢(如
-
非聚集索引
- 優點:適合高頻的等值查詢(如
WHERE column = value
),且支持覆蓋索引(查詢字段全部在索引中時無需回表)。 - 缺點:回表操作可能導致額外I/O開銷。
- 優點:適合高頻的等值查詢(如
4. 索引數量
-
聚集索引
每個表僅允許一個。 -
非聚集索引
每個表可創建多個(最多64個)。
5. 適用場景
-
聚集索引
適合主鍵查詢、范圍查詢或需要頻繁排序的場景。 -
非聚集索引
適合優化特定條件的查詢(如WHERE
、JOIN
)或需要覆蓋索引的場景。
6. 示例說明
假設有一個用戶表users
,結構如下:
CREATE TABLE users (id INT PRIMARY KEY,username VARCHAR(50),email VARCHAR(50),INDEX idx_username (username)
) ENGINE=InnoDB;
- 聚集索引:
id
字段,數據按id
順序存儲。 - 非聚集索引:
idx_username
索引,葉子節點存儲username
和對應的id
值。- 查詢
SELECT * FROM users WHERE username = 'Alice'
時:- 通過
idx_username
找到username='Alice'
對應的id
。 - 通過
id
到聚集索引中獲取完整數據行(回表)。
- 通過
- 查詢
7. 總結
特性 | 聚集索引 | 非聚集索引 |
---|---|---|
數據存儲 | 數據按索引順序物理存儲 | 數據獨立存儲,索引僅存儲指針或主鍵 |
數量 | 每表一個 | 每表多個 |
查詢效率 | 范圍查詢高效,直接獲取數據 | 可能需回表,覆蓋索引時高效 |
典型應用 | 主鍵、范圍查詢、排序 | 高頻條件查詢、覆蓋索引優化 |
理解兩者的區別有助于根據實際場景設計高效的索引策略。