在哪些列上添加索引?mysql
1. 一般選擇在where從句中,group by從句,order by從句,on從句中出現的列添加索引。
sql
在一些特殊狀況下,還會在select從句中所出現的列進行索引,當一個索引包括了查詢中的全部列,那麼稱這個索引就是覆蓋索引,當這個索引執行的頻率很是的高,並且查詢中所包括的列相對來講比較少的時候,就會經過覆蓋索引的方式對這個sql進行優化。數據庫
目的:使咱們所須要的數據徹底經過索引就可以獲取,而不用去查詢表的數據。
性能
2. 索引字段越小越好優化
由於數據庫中,數據的存儲是以頁爲單位的,若是在一頁中存儲的數據越多,一次IO操做獲取的數據量就越大,這樣對IO效率也會更高一些,因此索引字段是越小越好。
spa
3. 若是是創建聯合索引,須要考慮,哪一列放到聯合索引的前面最爲合適。 索引
聯合索引中會包含多個列,哪個列放到索引前頭對咱們的查詢優化最好呢?首先就要看哪一列的離散度更高,每每離散度更大的列,它的可選擇性就越高,所以放到聯合索引的前頭效果越好。
效率
(ノ*・ω・)ノ 那麼問題來了,若是判斷列的離散度?select
例如:數據
select * from payment where staff_id=2 and customer_id=584;
須要對這條sql創建一個聯合索引,那究竟是index(staff_id,customer_id)好呢,仍是index(customer_id,staff_id)好呢?哪個離散程度更好呢,須要執行一個統一的操做,首先查詢一下它們的惟一值都有多少個,惟一值越多,說明離散程度越好,可選擇性就越高,以下:
mysql> select count(distinct staff_id),count(distinct customer_id) from payment;
+--------------------------+-----------------------------+
| count(distinct staff_id) | count(distinct customer_id) |
+--------------------------+-----------------------------+
| 2 | 599 |
+--------------------------+-----------------------------+
1 row in set (0.10 sec)
因而可知,customer_id的韌度更高,可選擇性更好,所以,要創建聯合索引,就把customer_id放到聯合索引的前面,是更好的一種方式。
覆蓋索引(covering index)
MYSQL能夠利用索引返回select列表中的字段,而沒必要再去讀取數據文件。
包含全部知足查詢須要的數據的索引稱之爲覆蓋索引(covering index);
注意:若是使用覆蓋索引,必定要注意select列表中只取出須要的列,不能使用select *,由於若是將全部字段一塊兒作索引會致使索引文件過大,查詢性能降低。