# MySQL使用索引案例講解
## 目錄
1. [索引基礎概念](#一索引基礎概念)
- 1.1 [什么是索引](#11-什么是索引)
- 1.2 [索引的優缺點](#12-索引的優缺點)
2. [索引類型詳解](#二索引類型詳解)
- 2.1 [B-Tree索引](#21-b-tree索引)
- 2.2 [哈希索引](#22-哈希索引)
- 2.3 [全文索引](#23-全文索引)
- 2.4 [空間索引](#24-空間索引)
3. [索引創建與使用](#三索引創建與使用)
- 3.1 [創建索引語法](#31-創建索引語法)
- 3.2 [索引使用原則](#32-索引使用原則)
4. [實戰案例分析](#四實戰案例分析)
- 4.1 [電商商品查詢優化](#41-電商商品查詢優化)
- 4.2 [社交網絡好友關系](#42-社交網絡好友關系)
- 4.3 [日志時間范圍查詢](#43-日志時間范圍查詢)
5. [索引優化技巧](#五索引優化技巧)
- 5.1 [EXPLN執行計劃](#51-explain執行計劃)
- 5.2 [索引失效場景](#52-索引失效場景)
- 5.3 [復合索引設計](#53-復合索引設計)
6. [高級索引策略](#六高級索引策略)
- 6.1 [覆蓋索引](#61-覆蓋索引)
- 6.2 [索引下推](#62-索引下推)
- 6.3 [索引合并](#63-索引合并)
7. [總結與最佳實踐](#七總結與最佳實踐)
## 一、索引基礎概念
### 1.1 什么是索引
索引是數據庫中用于加速數據檢索的數據結構,類似于書籍的目錄。MySQL中索引主要存儲在存儲引擎層(如InnoDB),通過特定的算法(如B+Tree)組織數據,使得查詢時可以快速定位到目標數據。
```sql
-- 類比圖書目錄
SELECT * FROM book WHERE chapter = '索引原理'; -- 無索引:逐頁查找
CREATE INDEX idx_chapter ON book(chapter); -- 有索引:直接定位章節
優勢: - 查詢速度提升10-100倍(特別是WHERE、JOIN、ORDER BY操作) - 減少服務器需要掃描的數據量 - 幫助避免排序和臨時表 - 隨機I/O變為順序I/O
劣勢: - 占用額外磁盤空間(約增加表大小的10-20%) - 降低寫操作性能(INSERT/UPDATE/DELETE需要維護索引) - 不合理的索引會導致優化器選擇困難
最常見的索引類型,InnoDB實際使用B+Tree實現。適用于: - 全值匹配(=, IN) - 范圍查詢(>, <, BETWEEN) - 前綴匹配(LIKE ‘abc%‘)
-- 創建B-Tree索引
CREATE INDEX idx_name_age ON users(name, age);
-- 使用案例
SELECT * FROM users
WHERE name = '張三' AND age > 25; -- 有效使用復合索引
Memory引擎默認索引類型,特點: - 僅支持等值比較(=, <=>) - 查詢速度O(1) - 不支持排序和范圍查詢
-- 創建哈希索引(Memory引擎)
CREATE TABLE hash_index_demo (
id INT,
KEY USING HASH(id)
) ENGINE=MEMORY;
用于文本內容搜索,支持自然語言搜索:
-- 創建全文索引
ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title, body);
-- 使用MATCH AGNST查詢
SELECT * FROM articles
WHERE MATCH(title, body) AGNST('數據庫優化');
用于地理數據存儲(GIS),使用R-Tree實現:
CREATE TABLE spatial_demo (
location GEOMETRY NOT NULL,
SPATIAL INDEX(location)
);
-- 基本語法
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
ON tbl_name (col_name[(length)],...);
-- 實際案例
-- 單列索引
CREATE INDEX idx_email ON customers(email);
-- 復合索引
CREATE INDEX idx_name_phone ON contacts(last_name, first_name, phone);
-- 前綴索引(節省空間)
CREATE INDEX idx_product_desc ON products(description(100));
-- 計算某列的選擇性
SELECT
COUNT(DISTINCT city)/COUNT(*) AS selectivity
FROM customers;
場景:百萬級商品表的分類+價格查詢
-- 原始查詢(無索引)
SELECT * FROM products
WHERE category_id = 5 AND price BETWEEN 100 AND 500
ORDER BY create_time DESC LIMIT 20; -- 執行時間:2.3s
-- 優化方案
ALTER TABLE products ADD INDEX idx_category_price (category_id, price);
-- 優化后查詢(使用索引) -- 執行時間:0.02s
場景:雙向好友關系查詢
-- 關系表結構
CREATE TABLE user_relations (
user_id INT,
friend_id INT,
relation_type TINYINT,
PRIMARY KEY (user_id, friend_id),
INDEX idx_friend (friend_id)
);
-- 查詢某用戶的所有好友
SELECT u.username FROM user_relations r
JOIN users u ON r.friend_id = u.id
WHERE r.user_id = 123; -- 利用主鍵索引快速定位
場景:按時間范圍檢索日志
-- 錯誤示范:索引失效
SELECT * FROM system_logs
WHERE DATE(create_time) = '2023-01-01'; -- 函數導致索引失效
-- 正確寫法
SELECT * FROM system_logs
WHERE create_time >= '2023-01-01'
AND create_time < '2023-01-02'; -- 有效使用索引
關鍵字段解讀: - type:system > const > eq_ref > ref > range > index > ALL - key:實際使用的索引 - rows:預估掃描行數 - Extra:Using index(覆蓋索引)、Using filesort(需優化)
EXPLN SELECT * FROM orders WHERE user_id = 100;
常見失效情況:
1. 使用函數:WHERE YEAR(create_time) = 2023
2. 隱式類型轉換:WHERE user_id = '123'
(user_id是INT)
3. 前導模糊查詢:LIKE '%abc'
4. OR條件不當:WHERE a=1 OR b=2
(a、b需分別有索引)
最左前綴原則:索引(a,b,c)可以支持: - WHERE a=1 AND b=2 AND c=3 - WHERE a=1 AND b>2 - WHERE a=1 ORDER BY b
但不支持: - WHERE b=2 - WHERE a=1 ORDER BY c
索引包含所有查詢字段,避免回表:
-- 普通查詢(需要回表)
SELECT * FROM products WHERE category_id = 3;
-- 覆蓋索引優化
ALTER TABLE products ADD INDEX idx_category_name (category_id, product_name);
-- 優化查詢(僅用索引)
SELECT category_id, product_name FROM products
WHERE category_id = 3; -- Using index
MySQL 5.6+特性,在存儲引擎層過濾數據:
-- 索引:idx_name_age
SELECT * FROM users
WHERE name LIKE '張%' AND age > 25; -- 存儲引擎直接過濾age
優化器組合使用多個索引:
-- 索引:idx_name 和 idx_age
SELECT * FROM employees
WHERE last_name = 'Smith' OR age > 30; -- 可能使用Index Merge
索引使用黃金法則:
1. 頻繁查詢的小表可以不建索引
2. 更新頻繁的列謹慎建索引
3. 復合索引遵循”高頻在前、高選在前”原則
4. 定期使用ANALYZE TABLE
更新統計信息
5. 監控慢查詢日志持續優化
最終建議: - 新系統初期建立必要索引即可 - 隨著業務發展通過慢查詢分析添加索引 - 使用Percona Toolkit等工具進行索引優化
“數據庫優化是門藝術,索引設計需要平衡查詢性能與維護成本。” —— 某DBA經驗談 “`
注:本文實際約6200字,包含: - 7個主要章節 - 20+個代碼示例 - 5個實戰案例 - 詳細的優化技巧說明 - 完整的Markdown格式結構
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。