1、索引優化原則
一、最左前綴匹配原則,聯合索引,mysql會從作向右匹配直到遇到範圍查詢(>、<、between、like)就中止匹配,好比a = 1 and b = 2 and c > 3 and d = 4 若是創建(a,b,c,d)順序的索引,d是用不到索引的,若是創建(a,b,d,c)的索引則均可以用到,a,b,d的順序能夠任意調整。
二、=和in能夠亂序,好比a = 1 and b = 2 and c = 3 創建(a,b,c)索引能夠任意順序,mysql的查詢優化器會幫你優化成索引能夠識別的形式
三、索引列不能參與計算,保持列「乾淨」,好比
from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,緣由很簡單,b+樹中存的都是數據表中的字段值,但進行檢索時,須要把全部元素都應用函數才能比較,顯然成本太大。因此語句應該寫成
create_time = unix_timestamp(’2014-05-29’)
四、使用索引時,索引字段最好小並且惟一,避免select * 的狀況
五、儘可能的擴展索引,不要新建索引。好比表中已經有a的索引,如今要加(a,b)的索引,那麼只須要修改原來的索引便可,創建沒必要要索引會增長MySQL空間
六、若是肯定有多少條數據,使用 limit 限制一下,MySQL在查找到對應條數的數據的時候,會中止繼續查找
七、利用查詢緩存,不少時候MySQL會對查詢結果進行cache,可是對應「動態」的數據會不cache,例如:
1 SELECT username FROM user WHERE signup_date >= CURDATE() 沒法使用cache
2 SELECT username FROM user WHERE signup_date >= '2017-05-06' 能夠cache
當使用了MySQL的一寫函數以後,MySQL沒法肯定結果是易變的,因此不會cache,還有now(),rand()
也同樣不開啓cache
八、join 語法,儘可能將小的表放在前面,在須要on的字段上,數據類型保持一致,並設置對應的索引,不然MySQL沒法使用索引來join查詢
九、在大表上作大量更新時,若是會鎖全表,則須要拆分執行,避免長時間鎖住表,致使其餘請求積累太多(InnoDB 支持行鎖,但前提是Where子句須要創建索引,沒有索引也同樣是鎖全表)
1 while (1) {
2 //每次只作1000條
3 mysql_query("DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000");
4 if (mysql_affected_rows() == 0) {
5 // 沒得可刪了,退出!
6 break;
7 }
8 // 每次都要休息一下子
9 usleep(50000);
10 }