索引在存儲引擎層實現,不同引擎支援不同。MySQL 主流索引類型:
衍生索引:主鍵、唯一索引、複合索引、前綴索引等。
| 索引類型 | MyISAM | InnoDB | Memory |
|---|---|---|---|
| B-Tree | ✓ | ✓ | ✓ |
| Full-text | ✓ | 5.6+ ✓ | ✗ |
| Hash | ✗ | ✗ | ✓ |
| R-Tree | ✓ | ✗ | ✗ |
對複合索引所有列指定具體值(等值條件)。
-- 索引 (rental_date, inventory_id, customer_id) EXPLAIN SELECT * FROM rental WHERE rental_date='2005-05-25 17:22:10' AND inventory_id=373 AND customer_id=343;
對索引列進行範圍查找。
-- 索引 idx_fk_customer_id(customer_id) EXPLAIN SELECT * FROM rental WHERE customer_id >= 373 AND customer_id < 400;
僅使用複合索引最左列(或最左 N 列)查詢。
-- 索引 idx_payment_date(payment_date, amount, last_update) EXPLAIN SELECT * FROM payment WHERE payment_date='2006-02-14 15:16:03' AND last_update = '2006-02-15 22:12:32';
可用到索引,但非最左列 amount 缺失,僅用到部分索引(rows=182)。
查詢列全在索引中,Extra 顯示 Using index,無需回表。
EXPLAIN SELECT last_update FROM payment WHERE payment_date='2005-08-19 21:21:47' AND amount=4.99;
對字串列前綴建索引並查詢。
-- 索引 idx_title_desc_part(title(10), description(20)) EXPLAIN SELECT title FROM film_text WHERE title LIKE 'AFRICAN%';
EXPLAIN SELECT inventory_id FROM rental WHERE rental_date='2006-02-14 15:16:03' AND customer_id >= 300 AND customer_id <= 400;
EXPLAIN SELECT * FROM payment WHERE rental_id IS NULL;
LIKE '%...%' 以萬用字元開頭EXPLAIN SELECT * FROM actor WHERE last_name LIKE '%NI%';
優化:用子查詢先取主鍵再回表。
EXPLAIN SELECT * FROM actor WHERE last_name=1; -- 不用索引 EXPLAIN SELECT * FROM actor WHERE last_name='1'; -- 用索引
EXPLAIN SELECT * FROM payment WHERE amount=3.98 AND last_update='2006-02-15 22:12:32';
如 title LIKE 'S%' 回傳比例過大,優化器放棄索引。
OR 條件任一列無索引EXPLAIN SELECT * FROM payment WHERE customer_id=203 OR amount=3.96; -- amount 無索引導致全表掃描