索引是提升查詢性能的關鍵。無索引時 MySQL 全表掃描(Type=ALL),建立索引後可將掃描行數從數十萬降至 1,查詢耗時從秒級降至毫秒級。
CREATE TABLE user(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
email VARCHAR(40) NOT NULL,
PRIMARY KEY (id)
);
特點:唯一、非空、聚簇索引(InnoDB),每表僅一個。
CREATE INDEX idx_name ON user(name(20));
特點:無唯一性限制,支持前綴索引(節省空間,如 name(20))。
CREATE UNIQUE INDEX idx_email ON user(email);
特點:值唯一,允許 NULL(多個 NULL 不衝突)。
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body)
) ENGINE=MyISAM;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST('database');
特點:僅 MyISAM 支持(5.6+ InnoDB 也支持),自然語言搜索,返回相關度評分。
CREATE TABLE test(
id INT NOT NULL PRIMARY KEY,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
INDEX name (last_name, first_name)
);
生效查詢:
WHERE last_name='Widenius' ✓WHERE last_name='Widenius' AND first_name='Michael' ✓WHERE first_name='Michael' ✗(非最左列)-- 未建索引前
EXPLAIN SELECT name FROM fps WHERE name='李武';
-- type=ALL, rows=1041, Extra=Using where
-- 建立索引
CREATE INDEX idx_name ON fps(name);
-- 建索引後
EXPLAIN SELECT name FROM fps WHERE name='李武';
-- type=ref, rows=1, Extra=Using where; Using index
| 列 | 含義 | 優化目標 |
|---|---|---|
| type | 連接類型:system>const>eq_ref>ref>range>index>ALL | 避免 ALL,達到 ref/range |
| possible_keys | 可能用到的索引 | 確保目標索引在列表中 |
| key | 實際使用的索引 | 非 NULL 表示命中 |
| key_len | 索引使用長度(字節) | 驗證復合索引列使用情況 |
| rows | 預估掃描行數 | 越接近 1 越好 |
| Extra | 額外信息 | Using index(覆蓋索引)佳;Using filesort/Using temporary 需優化 |
myisamchk 修復、myisampack 壓縮innodb_file_per_table=1)xtrabackup 或 mysqldump --single-transaction| 場景 | 推薦引擎 | 理由 |
|---|---|---|
| Web 讀多寫少、全文搜索 | MyISAM | 讀性能強、原生全文索引 |
| 事務業務、高並發寫入、外鍵 | InnoDB | ACID、行級鎖、崩潰恢復 |
| 臨時計算、緩存表 | MEMORY | 內存級速度 |
WHERE id+1=5 失效)SELECT id, name FROM t WHERE email=? 含 INDEX(email, name)ANALYZE TABLE 更新統計信息,OPTIMIZE TABLE 整理碎片slow_query_log + EXPLAIN 持續優化