一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Mysql - MYSQL Left Join優化(10秒優化到20毫秒內)

MYSQL Left Join優化(10秒優化到20毫秒內)

2022-01-25 17:24幽寒冰魄 Mysql

在實際開發中,相信大多數人都會用到join進行連表查詢,但是有些人發現,用join好像效率很低,而且驅動表不同,執行時間也不同。那么join到底是如何執行的呢,本文就詳細的介紹一下

結合工作中的內容和大家分享一次Left Jon優化的過程,希望能給同學們新的思路。

【功能背景】

    我們需要按照用戶訂單號和商戶號統計出購買的商品數量和售后的商品數量。涉及到的表和關系見下圖:

很不幸工程師在起初進行表結構設計的時候沒有在商戶訂單表中記錄下購買的商品總數,在商戶訂單的售后單中也沒記錄下售后的商品數量。

【原始的SQL】

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
select
  o.no,s_order.no,sum(s_item.count),sum(after_sale_item.count)
  from
  buyer_order o
  left join seller_order s_order on o.id = s_order.buyer_order_id
  left join seller_order_item s_item on s_order.id = s_item.seller_order_id
  left join seller_order_after_sale after_sale on s_order.id = after_sale.seller_order_id
  left join seller_order_after_sale_item after_sale_item on after_sale.id = after_sale_item.after_sale_id
where o.add_time >='2019-05-01'
group by
  o.id,s_order.id
order by
  o.id
limit 0,10

以上SQL幾個關鍵字段都使用了索引。  

【原始的SQL分析】

這是一條很常規的SQL,邏輯上也沒什么毛病

這條SQL中有較多的連接查詢,如果隨著售后單的增加,連接的數據就會更多

將符合條件的數據都加載到內存后按照 order.id,s_order.id 進行分組統計,如果有100W的數據會怎樣?如果你用代碼去實現這么一段統計你會怎么做?

將統計完的數據再按照 order.id 進行排序,取出前10條數據。

從以上的SQL發現需要將符合條件的所有的數據加載到內存后要進行分組,統計,排序,最后再進行分頁。我們能不能減少數據的加載數量呢?能不能減少數據庫CPU的使用量,能不能先取少量的數據再統計呢?

基于以上的問題,我們進行了優化

【分析步驟】

作為旁觀者一開始不了解我們功能需要輸出什么樣的數據,所以我們一開始要了解每張表存儲的是什么樣的數據,彼此之間的關系是什么。

我們忘記原來的SQL是什么樣的,按照我們需要的數據,再次重新的思考,不要再陷入原來的SQL的漩渦中。

針對上面提出的問題,如何減少數據的加載?能不能先分頁數據,再對分頁的數據進行單獨的統計呢?

那么我們是不是需要對group by進行優化,我們要想辦法先分頁

大家是否想到了一些方法?

【優化后的SQL】

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
select
  o.id,o.no,s_order.no,
  (select sum(sot.count) from seller_order so
    left join seller_order_item sot on so.id = sot.seller_order_id
        where so.id =s_order.id ),
  (select sum(osat.count) from seller_order_after_sale osa
    left join seller_order_after_sale_item osat on osa.id = osat.after_sale_id
        where osa.seller_order_id = s_order.id )
  from
  buyer_order o
  left join seller_order s_order on o.id = s_order.buyer_order_id
where o.addTime >='2019-05-01'
order by
  o.id
limit 0,10

【優化的SQL分析】

  1. 很直觀的發現,我們把group by去掉了,因為按照 order.id,s_order.id 分組,實際只對 buyer_order和seller_order表進行連接,邏輯上是一樣的進行了分組。
  2. group by不使用的話我們就減少了CPU對數據分組的處理,而且我們只連接主要的表數據,減少了加載到內存中的數據。
  3. 以上的操作就完成了我們之前說的先對數據分頁。我們取出了10條數據。
  4. 接著我們再對10條數據的銷售出去的商品數量和售后的數量進行統計
  5. 這時候大家發現,我們其實只對分頁出來的10條數據進行統計,原來是將所有的數據分組統計后取10條??梢园l現我們這樣操作大大減少了對數據的統計處理。我們只需要統計我們需要的數據。

以上優化的效果可能遠遠超出大家的想象。

實際工作中連表的數比我們例子中的要多,未優化的SQL在執行未分頁的時候發現一共有70萬的數據,我們分頁取出10條數據花了10+秒以上的時間,數據量不大但是大部分的時間都消耗在了分組和數據統計,大家可以試著寫一段代碼對這些數據進行分組和統計,就能明白其中的復雜性。

而實際上無論取出10條和全部取出,時間基本上一樣的(不考慮IO),因為先進行了統計。

優化后的SQL,加載到內存中只有2萬左右的數據,而且不進行統計,先取出10條數據,然后再對10條數據進行統計,邏輯上比之前的簡單多了。優化后的SQL執行時間在20毫秒以內。

其實如果在訂單表和售后表都記錄了對應的數量,連表數還要少,還不需要進行子查詢。有時候設計表的時候還是需要考慮一下統計的需要。

到此這篇關于MYSQL Left Join優化(10秒優化到20毫秒內)的文章就介紹到這了,更多相關MYSQL Left Join優化內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/cdnsa/article/details/93609503

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产日韩欧美色视频色在线观看 | 欧美老人与小伙子性生交 | 99爱在线观看精品视频 | 成人永久免费福利视频网站 | 91久久综合 | 太大了轻点阿受不了小说h 四色6677最新永久网站 | 2020国语对白露脸 | 色哟呦| 四虎精品成人免费观看 | 免费观看的毛片 | 色噜噜狠狠色综合 | 果冻传媒天美传媒乌鸦传媒 | 亚欧精品在线观看 | 91拍拍| 国产精品视频人人做人人爱 | 98pao强力打造高清免费 | 图片亚洲va欧美va国产综合 | 天堂成人影院 | 四虎tv| 欧美一级视频免费观看 | 91视频一区 | 黄动漫软件车车好快的车车 | 2020韩国r级理论片在线观看 | 99精品视频只99有精品 | 久久久免费观成人影院 | 欧美特黄三级在线观看 | 精品一区在线 | 国产成人精品一区二区仙踪林 | 大学生特黄特色大片免费播放 | 欧美日韩亚洲国内综合网俺 | 亚洲国产日韩欧美在线vip1区 | 色综合久久日韩国产 | 乳女教师欲乱动漫无修版动画3d | 五月色婷婷久久综合 | 免费看欧美一级特黄a大片一 | 97操 | 成人精品视频 成人影院 | 91porn最新网址 | 国产区成人综合色在线 | 国产精品片 | 特级毛片免费观看视频 |