參考:
MySQL 索引優化全攻略
索引建立的規則
1.能創建唯一索引就創建唯一索引
2.為經常需要排序、分組和聯合操作的字段建立索引
3.為常作為查詢條件的字段建立索引
如果某個字段經常用來做查詢條件,那么該字段的查詢速度會影響整個表的查詢速度。
因此,為這樣的字段建立索引,可以提高整個表的查詢速度。
4.盡量使用前綴來索引
如果索引字段的值很長,最好使用值的前綴來索引。
例如,TEXT 和 BLOG 類型的字段,進行全文檢索,會很浪費時間。如果只檢索字段的前面的若干個字符,這樣可以提高檢索速度。
5.限制索引的數目
索引的數目不是越多越好。每個索引都需要占用磁盤空間,索引越多,需要的磁盤空間就越大。
修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。
6.刪除不再使用或者很少使用的索引
表中的數據被大量更新,或者數據的使用方式被改變后,原有的一些索引可能不再需要。數據庫管理員應當定期找出這些索引,將它們刪除,從而減少索引對更新操作的影響。
7.建議在多表join的時候盡量少join幾張表,因為一不小心就是一個笛卡爾乘積的恐怖掃描,另外,建議盡量使用left join,以少關聯多。因為使用 join 的話,第一張表是必須的全掃描的,以少關聯多就可以減少這個掃描次數。
什么樣的 SQL 不走索引
沒有查詢條件,或者查詢條件沒有索引
-- 沒有查詢條件
mysql> explain select * from city;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | city | ALL | NULL | NULL | NULL | NULL | 4188 | NULL |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
-- 查詢條件沒有索引
mysql> explain select District from city;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | city | ALL | NULL | NULL | NULL | NULL | 4188 | NULL |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
查詢的結果占總數據的 15% 以上
-- 占總數據的18%,沒走索引
mysql> explain select * from city where population > 400000;
-- 占總數據的15%,走了索引
mysql> explain select * from city where population > 450000;
-- 如果數據量查詢就是表中大部分數據,可以用 limit 做限制
mysql> explain select * from city where population > 400000 limit 100;
查詢條件字段參與了運算
-- 在 =號 左側有特殊符號,不走索引
mysql> explain select * from city where id-1=1;
-- 在 =號 右側有特殊符號,走索引
mysql> explain select * from city where id=3-1;
字符串與數字比較不使用索引
CREATE TABLE `a` (`a` char(10));
EXPLAIN SELECT * FROM `a` WHERE `a`="1" -- 走索引
EXPLAIN SELECT * FROM `a` WHERE `a`=1 -- 不走索引
like "%_" 百分號在最前面不走
SELECT * FROM `houdunwang` WHERE `uname` LIKE'后盾%' -- 走索引
SELECT * FROM `houdunwang` WHERE `uname` LIKE "%后盾%" -- 不走索引
組合索引的順序
ALTER TABLE students ADD INDEX union_key(a,b,c);
-- 走索引;
SELECT * FROM students where a= 'wqh' and b= 'wqhhobby' and c= 18;
SELECT * FROM students where a= 'wqh' and c= 18 and b= 'wqhhobby';
SELECT * FROM students where b= 'wqhhobby' and a= 'wqh' and c= 18;
SELECT * FROM students where a= 'wqh' and b= 'wqhhobby';
SELECT * FROM students where b= 'wqhhobby' and a= 'wqh';
SELECT * FROM students where a= 'wqh';
-- 部分走索引;
SELECT * FROM students where a= 'wqh' and c= 18; -- a 走索引,c 不走
SELECT * FROM students where a= 'wqh' order by c; -- a 走索引,c 不走
-- 不走索引;
SELECT * FROM students where b= 'wqhhobby' and c= 18;
SELECT * FROM students where c= 18;
SELECT * FROM students where b= 'wqhhobby';