mysql查詢優化~group by和order by


一 簡介:聊聊group by的分組
二 explain體現
    extra下
   1 using tempoary
   2 using tempoary && using filesort
   3 using filesort
   4 none
三 實現方式
  1 定義
    GROUP BY 實際上也同樣會進行排序操作,而且與ORDER BY 相比,GROUP BY 主要只是多了排序之后的分組操作,所以group by同樣可以利用到索引
  2 實現方式
    使用松散(Loose)索引掃描實現 GROUP BY 
   1 單一表查詢
   2 Group by中只有最左前綴列,沒有其他列
   3 只支持max和min聚合,而且,要聚合的列必須是group by中列所在的索引(未測試)
   4 未被group by引用的索引其他部分必須是常量(不理解)
   5 不支持前綴索引。
  eg
   -- 因為聚合函數不是max或者min
  SELECT c1, SUM(c2) FROM t1 GROUP BY c1;
  -- 因為不符合最左前綴原則
  SELECT c1, c2 FROM t1 GROUP BY c2, c3;
  -- 查詢涉及到了索引的一部分,緊跟group by中的列,但是沒有常量等值語句,加上 WHERE c3 = const就好了
  SELECT c1, c3 FROM t1 GROUP BY c1, c2;
  2 使用臨時表實現 GROUP BY
    處理過程 通過where索引過濾 然后放置在臨時表中再進行分組+排序
四 優化
  1 盡量使用group by 的分組利用到聯合索引
  2 盡量添加order by null避免filesort
五  order by 使用場景解析

    select * from table  order by a1   當a1有索引的時候是可以利用到索引的

    select * from table where a1=1 order by b1   當a 和 b為聯合索引且a為最左的時候 是可以利用到索引的

    select * from table  order by  a1 desc, b1   利用8.0的特性創建制定順序的聯合索引是可以的,其他情況下是不能利用到索引,因為聯合索引只能按照一個順序進行查找

    select * from table order by a1,b1              當a和b為聯合索引時是可以利用到索引的

    select * from table  where a1 > n  order by  a1  這種情況下根據數據量的分布可能會利用到icp特性或者應用不到索引

    select * from table   where a1 = n and b1 > n order by b1  這種情況下可能會遇到ICP特性

    select * from table group a1 order by b1    這種情況下不能利用索引

    相關排序參數 sort_buffer_size 先利用這個參數內存,只有內存不夠了才會在磁盤形成臨時文件

六  order by  與分頁操作

      select *  from  table  where  a =  b =  order by id limit 10

     現象 通過explain 走的是ID主鍵  奇怪現象   asc  與 desc 相差速度很大,但是explain確是相同

     分析  通過explain分析可知,執行順序為 先根據order by進行排序 然后再進行條件過濾 最后分頁取操作. asc與desc執行速度的不同其實也可以推測. 那么就是結果集的數據都集中在正向而不是反向.那么這樣desc 和asc的速度不一樣就可以得知了.而limit 小結果集的加入讓sql優化器更傾向於order by 索引

     解決方法:  1 order by 的排序項最好能參與到 where條件過濾中,即是聯合索引的一部分  2 調大 limit 結果集(根據業務決定) 3 采用延遲join

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM