溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在MySQL中使用sum、case和when優化統計查詢

發布時間:2021-03-18 15:25:18 來源:億速云 閱讀:254 作者:Leah 欄目:開發技術

怎么在MySQL中使用sum、case和when優化統計查詢?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

表結構如下:

CREATE TABLE `statistic_order` (
 `oid` bigint(20) NOT NULL,
 `o_source` varchar(25) DEFAULT NULL COMMENT '來源編號',
 `o_actno` varchar(30) DEFAULT NULL COMMENT '活動編號',
 `o_actname` varchar(100) DEFAULT NULL COMMENT '參與活動名稱',
 `o_n_channel` int(2) DEFAULT NULL COMMENT '商城平臺',
 `o_clue` varchar(25) DEFAULT NULL COMMENT '線索分類',
 `o_star_level` varchar(25) DEFAULT NULL COMMENT '訂單星級',
 `o_saledep` varchar(30) DEFAULT NULL COMMENT '營銷部',
 `o_style` varchar(30) DEFAULT NULL COMMENT '車型',
 `o_status` int(2) DEFAULT NULL COMMENT '訂單狀態',
 `syctime_day` varchar(15) DEFAULT NULL COMMENT '按天格式化日期',
 PRIMARY KEY (`oid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

項目需求是這樣的:

統計某段時間范圍內每天的來源編號數量,其中來源編號對應數據表中的o_source字段,字段值可能為CDE,SDE,PDE,CSE,SSE。

怎么在MySQL中使用sum、case和when優化統計查詢

來源分類隨時間流動

一開始寫了這樣一段SQL:

select S.syctime_day,
 (select count(*) from statistic_order SS where SS.syctime_day = S.syctime_day and SS.o_source = 'CDE') as 'CDE',
 (select count(*) from statistic_order SS where SS.syctime_day = S.syctime_day and SS.o_source = 'CDE') as 'SDE',
 (select count(*) from statistic_order SS where SS.syctime_day = S.syctime_day and SS.o_source = 'CDE') as 'PDE',
 (select count(*) from statistic_order SS where SS.syctime_day = S.syctime_day and SS.o_source = 'CDE') as 'CSE',
 (select count(*) from statistic_order SS where SS.syctime_day = S.syctime_day and SS.o_source = 'CDE') as 'SSE'
 from statistic_order S where S.syctime_day > '2016-05-01' and S.syctime_day < '2016-08-01' 
 GROUP BY S.syctime_day order by S.syctime_day asc;

這種寫法采用了子查詢的方式,在沒有加索引的情況下,55萬條數據執行這句SQL,在workbench下等待了將近十分鐘,最后報了一個連接中斷,通過explain解釋器可以看到SQL的執行計劃如下:

怎么在MySQL中使用sum、case和when優化統計查詢

每一個查詢都進行了全表掃描,五個子查詢DEPENDENT SUBQUERY說明依賴于外部查詢,這種查詢機制是先進行外部查詢,查詢出group by后的日期結果,然后子查詢分別查詢對應的日期中CDE,SDE等的數量,其效率可想而知。

在o_source和syctime_day上加上索引之后,效率提高了很多,大概五秒鐘就查詢出了結果:

怎么在MySQL中使用sum、case和when優化統計查詢

查看執行計劃發現掃描的行數減少了很多,不再進行全表掃描了:

怎么在MySQL中使用sum、case和when優化統計查詢

這當然還不夠快,如果當數據量達到百萬級別的話,查詢速度肯定是不能容忍的。一直在想有沒有一種辦法,能否直接遍歷一次就查詢出所有的結果,類似于遍歷java中的list集合,遇到某個條件就計數一次,這樣進行一次全表掃描就可以查詢出結果集,結果索引,效率應該會很高。在老大的指引下,利用sum聚合函數,加上case...when...then...這種“陌生”的用法,有效的解決了這個問題。
具體SQL如下:

 select S.syctime_day,
 sum(case when S.o_source = 'CDE' then 1 else 0 end) as 'CDE',
 sum(case when S.o_source = 'SDE' then 1 else 0 end) as 'SDE',
 sum(case when S.o_source = 'PDE' then 1 else 0 end) as 'PDE',
 sum(case when S.o_source = 'CSE' then 1 else 0 end) as 'CSE',
 sum(case when S.o_source = 'SSE' then 1 else 0 end) as 'SSE'
 from statistic_order S where S.syctime_day > '2015-05-01' and S.syctime_day < '2016-08-01' 
 GROUP BY S.syctime_day order by S.syctime_day asc;

關于MySQL中case...when...then的用法就不做過多的解釋了,這條SQL很容易理解,先對一條一條記錄進行遍歷,group by對日期進行了分類,sum聚合函數對某個日期的值進行求和,重點就在于case...when...then對sum的求和巧妙的加入了條件,當o_source = 'CDE'的時候,計數為1,否則為0;當o_source='SDE'的時候......

這條語句的執行只花了一秒多,對于五十多萬的數據進行這樣一個維度的統計還是比較理想的。

怎么在MySQL中使用sum、case和when優化統計查詢

通過執行計劃發現,雖然掃描的行數變多了,但是只進行了一次全表掃描,而且是SIMPLE簡單查詢,所以執行效率自然就高了:

怎么在MySQL中使用sum、case和when優化統計查詢

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女