1.order by優化mysql
2.group by優化算法
3.Dinstinct 優化sql
1.order by優化函數
實現方式:性能
1. 根據索引字段排序,利用索引取出的數據已是排好序的,直接返回給客戶端;優化
2. 沒有用到索引,將取出的數據進行一次排序操做後返回給客戶端。spa
EXPLAIN SELECT m.id,m.subject,c.content FROM group_message m,group_message_content c WHERE m.group_id = 1 AND m.id = c.group_msg_id ORDER BY m.user_id\G;
optimizer對query進行了優化,它會按照m.user_id上的索引順序來訪問數據,這樣獲取的數據已是排好序的。指針
這種利用索引實現數據排序的方法是 MySQL 中實現結果集排序的最佳作法,利用已有的索引避免實際的排序計算所帶來的資源消耗。blog
若是沒有用到索引,mysql就會將取出的數據按照必定的排序算法進行排序,而後再把排好序的數據返回給客戶端。mysql中主要使用兩種排序算法:排序
1. 取出用於排序的條件字段和指向相應數據行的指針,在sort buffer中對條件進行排序,排好序以後利用指針取出數據行中的請求數據,而後返回給客戶端;
2. 取出用於排序的條件字段和其它全部請求數據,將不用於排序的字段存放在一塊內存中,而後在sort buffer中對條件字段進行排序,排好序後利用行指針將在內存中的數據進行匹配合並結果集,而後將排好序的數據返回給客戶端。(減小數據的二次訪問,節省了IO操做)
3.當用於排序的字段存在在多個表中,或者在排序以前要先通過join操做,mysql必須先把join的結果集放入一個臨時表,以後再把臨時表中的數據取到sort buffer裏進行排序。
優化方式:
1. 加大max_length_for_sort_data參數的設置。當須要取出的全部數據長度小於這個參數的值的時候,mysql將採用第二重排序算法,不然,使用第一種算法,因此只要內存充足就能夠設置足夠大的值來讓mysql採用改進的排序算法。
2. 去掉沒必要要的字段。
3. 增大sort_buffer_size參數的值。當mysql對條件字段進行排序時,若是須要排序字段的總長度大於該參數的值的時候,mysql就會對須要排序的字段使用臨時表進行分段,這樣也會有性能的消耗。
2.group by優化
group by的實現過程除了要使用排序操做外,還要進行分組操做,若是使用到一些聚合函數,還要進行相應的聚合計算。
實現方式:
1. 使用鬆散(Loose)索引掃描實現group by,所謂的鬆散索引掃描,就是mysql不須要掃描全部知足條件的索引鍵便可完成group by操做
2. 使用緊湊(Tight)索引掃描實現group by,緊湊索引與鬆散索引最主要的區別就是在須要掃描索引的時候,緊湊索引讀取全部知足條件的索引鍵,而後再來使用group by操做獲得相應的結果。
3.當optimizer沒法找到合適的索引能夠利用的時候,就會選擇將讀取的數據放入臨時表中來完成group by操做。group by操做想要利用索引,必須知足group by字段必須同時存放於同一個索引中,且該索引是一個有序索引,並且,使用不一樣的聚合函數也會影響是否使用索引來實現group by操做。
優化方式:
1. 儘量利用索引而且是鬆散索引來完成group by操做,這的依靠調整索引或者調整query來實現;
2. 當沒法利用索引的時候,必需要提供足夠的sort_buffer_size來供mysql完成排序操做,以前介紹過,否則mysql會將須要排序的字段進行分段排序,會影響性能。除此以外儘可能不要對大結果集進行group by操做,由於一旦數據量超過系統最大臨時表大小時,mysql會將臨時表裏的數據copy到磁盤上而後再進行操做,性能會成數量級的降低。
3.Dinstinct 優化
實現方式:
distinct的實現原理同group by相似,實現過程只是在group by以後只取出每一組中的第一條記錄,因此distinct一樣能夠利用鬆散或者緊湊索引來實現,不一樣的是,當沒法利用索引實現distinct時,mysql一樣會將數據取出放進一個臨時表,不過不會對臨時表進行排序操做。
優化方式:
儘可能使用索引,沒法使用索引的時候,確保不要在大結果集上進行distinct操做,磁盤上的IO操做和內存中的IO操做性能徹底不是一個數量級的差距。