多列索引和索引順序: 出現(xiàn)多個索引做相交操作時(多個AND條件),通常來說一個包含所有相關(guān)列的索引要優(yōu)于多個獨立索引。 在選擇性高的字段上建立索引,可以讓MySQL在查詢時過濾掉更多的行。對于多列索引,哪個索引字段在前面,取決于索引的選擇性的高低。選擇性高的索引排在前面,有利于提高查詢效率。例如聯(lián)合索引(user_group_id,trade_amount)用戶的群組肯定比訂單的交易金額的選擇性高。 覆蓋索引:如果一個索引包含或者說覆蓋所有需要查詢的字段的值,那么就沒有必要再回表查詢,這就稱為覆蓋索引。覆蓋索引是非常有用的工具,可以極大的提高性能,因為查詢只需要掃描索引會帶來許多好處: 優(yōu)化關(guān)聯(lián)查詢:以小表驅(qū)動大表。 子查詢盡量換成join。這是因為join,MySQL不需要在內(nèi)存中創(chuàng)建臨時表來完成這個邏輯上的需求。 確保任何的GROUP BY和ORDER BY中的表達式只涉及到一個表中的列,這樣MySQL才有可能使用索引來優(yōu)化。 優(yōu)化LIMIT分頁:一個常見的問題是當偏移量非常大的時候,比如:LIMIT 10000 20這樣的查詢,MySQL需要查詢10020條記錄然后只返回20條記錄,前面的10000條都將被拋棄,這樣的代價非常高。優(yōu)化這種查詢一個最簡單的辦法就是盡可能的使用覆蓋索引掃描,而不是查詢所有的列。然后根據(jù)需要做一次關(guān)聯(lián)查詢再返回所有的列。對于偏移量很大時,這樣做的效率會提升非常大。考慮下面的查詢: 修改前:SELECT film_id,description FROM film ORDER BY title LIMIT 50,5; 修改后: SELECT film.film_id,film.description FROM film INNER JOIN ( SELECT film_id FROM film ORDER BY title LIMIT 50,5 ) AS tmp USING(film_id); 優(yōu)化UNION:除非確實需要服務(wù)器去重,否則就一定要使用UNION ALL,如果沒有ALL關(guān)鍵字,MySQL會給臨時表加上DISTINCT選項,這會導(dǎo)致整個臨時表的數(shù)據(jù)做唯一性檢查,這樣做的代價非常高。 避免導(dǎo)致索引失效的寫法 (1)負向條件查詢不能使用索引(not in/not exists都不是好習(xí)慣) (2)前導(dǎo)模糊查詢不能使用索引(like'XX%') (3)數(shù)據(jù)區(qū)分度不大的字段不宜使用索引 (4)在屬性上進行計算不能命中索引 (5)復(fù)合索引最左前綴不滿足 強制類型轉(zhuǎn)換會全表掃描 如果明確知道只有一條結(jié)果返回,limit 1能夠提高效率 2)合理設(shè)置mysql的部分參數(shù),達到最高效。
thread_pool_size:如果主引擎(primary storage engine)為InnoDB,thread_pool_size最佳設(shè)置可能在16和36之間,最常見的優(yōu)化值傾向于24到36。 thread_pool_stall_limit:用處理被阻塞和長時間運行的語句,確保服務(wù)器不完全被阻塞。設(shè)置過長會導(dǎo)致線程被阻塞,引起性能問題。 tmp_table_size:通過設(shè)置tmp_table_size選項來增加一張臨時表的大小,例如做order by ,GROUP BY操作生成的臨時表。如果調(diào)高該值,MySQL同時將增加heap表的大小,可達到提高聯(lián)接查詢速度的效果,建議盡量優(yōu)化查詢,要確保查詢過程中生成的臨時表在內(nèi)存中,避免臨時表過大導(dǎo)致生成基于硬盤的MyISAM表。