Session重疊問題學習(四)--再優化
接前文:
需求描述和第一版解決方案(執行時間90秒)
http://blog.itpub.net/29254281/viewspace-2150229/
優化和修改bug的版本(執行時間25秒)
http://blog.itpub.net/29254281/viewspace-2150259/
我覺得在集合思維處理方式中,前文已經達到最優了.
如果放棄完全的集合處理思維,實際上還可以更加的優化.
前文的幾個問題.
1.引入了過多的表結構.
2.寫表本身也花費了時間.
3.前文按天批處理,粒度還是細了.應該一把批量全出最快.
4.前文計算最小間隔範圍的部分,因為應用集合化思維,不好理解效能還差.
前文計算最小間隔範圍的部分如下
該部分使用集合處理方式,不好理解效能還差.
這塊可以通過遊標寫臨時表輕易解決。
本質上最小範圍就是
每天每個房間每個記錄的開始時間和結束時間都扣出來作為一行 排序。
然後找到每個時間最近的下一個時間,作為最小時間範圍.
如果使用遊標,遍歷一遍即可.
都內聚到一個過程之後,不需要建立額外的普通表,直接在過程中建立臨時表.實現高內聚,低耦合.
call p
過程返回的結果即為最終結果.
三次測試耗時均低於 10.3秒
需求描述和第一版解決方案(執行時間90秒)
http://blog.itpub.net/29254281/viewspace-2150229/
優化和修改bug的版本(執行時間25秒)
http://blog.itpub.net/29254281/viewspace-2150259/
我覺得在集合思維處理方式中,前文已經達到最優了.
如果放棄完全的集合處理思維,實際上還可以更加的優化.
前文的幾個問題.
1.引入了過多的表結構.
2.寫表本身也花費了時間.
3.前文按天批處理,粒度還是細了.應該一把批量全出最快.
4.前文計算最小間隔範圍的部分,因為應用集合化思維,不好理解效能還差.
前文計算最小間隔範圍的部分如下
- select roomid,CAST(starttime as DATETIME) starttime,CAST(endtime as DATETIME) endtime from (
- select @d as starttime,@d:=d,v3.roomid,v3.d endtime from (
- select distinct roomid,
- case
- when nums.id=1 then v1s
- when nums.id=2 then v1e
- when nums.id=3 then v2s
- when nums.id=4 then v2e
- end d from (
- select v1.roomid, v1.s v1s,v1.e v1e,v2.s v2s,v2.e v2e
- from t1 v1
- inner join t1 v2 on ((v1.s between v2.s and v2.e or v1.e between v2.s and v2.e ) and v1.roomid=v2.roomid)
- where v2.roomid in(select distinct roomid from t1 where date(s)=pTime)
- and v2.s>=pTime and v2.s<(pTime+interval '1' day) and (v2.roomid,v2.userid,v2.s,v2.e)!= (v1.roomid,v1.userid,v1.s,v1.e)
- ) a,nums where nums.id<=4
- order by roomid,d
- ) v3,(select @d:='') vars
- ) v4 where starttime!=''
該部分使用集合處理方式,不好理解效能還差.
這塊可以通過遊標寫臨時表輕易解決。
本質上最小範圍就是
每天每個房間每個記錄的開始時間和結束時間都扣出來作為一行 排序。
然後找到每個時間最近的下一個時間,作為最小時間範圍.
如果使用遊標,遍歷一遍即可.
- DELIMITER $$
- CREATE DEFINER=`root`@`localhost` PROCEDURE `p`()
- BEGIN
- declare done int default 0;
- declare v_roomid bigint;
- declare v_start timestamp;
- declare v_end timestamp;
- declare cur_test CURSOR for select roomid,s,e from t1 ;
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
- drop table if exists t1;
- drop table if exists tmp_time_point;
- CREATE temporary TABLE `t1` (
- `roomid` int(11) NOT NULL DEFAULT '0',
- `userid` bigint(20) NOT NULL DEFAULT '0',
- `s` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- `e` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- primary KEY `roomid` (`roomid`,`s`,`e`,`userid`)
- ) ENGINE=InnoDB;
- create temporary table tmp_time_point(
- roomid bigint,
- timepoint timestamp,
- primary key(roomid,timepoint)
- ) engine=memory;
- insert into t1
- select distinct
- roomid,
- userid,
- if(date(s)!=date(e) and id>1,date(s+interval id-1 day),s) s,
- if(date(s+interval id-1 day)=date(e) ,e,date_format(s+interval id-1 day,'%Y-%m-%d 23:59:59')) e
- from (
- SELECT DISTINCT s.roomid, s.userid, s.s, (
- SELECT MIN(e)
- FROM (SELECT DISTINCT roomid, userid, roomend AS e
- FROM u_room_log a
- WHERE NOT EXISTS (SELECT *
- FROM u_room_log b
- WHERE a.roomid = b.roomid
- AND a.userid = b.userid
- AND a.roomend >= b.roomstart
- AND a.roomend < b.roomend)
- ) s2
- WHERE s2.e > s.s
- AND s.roomid = s2.roomid
- AND s.userid = s2.userid
- ) AS e
- FROM (SELECT DISTINCT roomid, userid, roomstart AS s
- FROM u_room_log a
- WHERE NOT EXISTS (SELECT *
- FROM u_room_log b
- WHERE a.roomid = b.roomid
- AND a.userid = b.userid
- AND a.roomstart > b.roomstart
- AND a.roomstart <= b.roomend)
- ) s, (SELECT DISTINCT roomid, userid, roomend AS e
- FROM u_room_log a
- WHERE NOT EXISTS (SELECT *
- FROM u_room_log b
- WHERE a.roomid = b.roomid
- AND a.userid = b.userid
- AND a.roomend >= b.roomstart
- AND a.roomend < b.roomend)
- ) e
- WHERE s.roomid = e.roomid
- AND s.userid = e.userid
- ) t1 ,
- nums
- where nums.id<=datediff(e,s)+1
- ;
- open cur_test;
- repeat
- fetch cur_test into v_roomid, v_start,v_end;
- if done !=1 then
- insert ignore into tmp_time_point(roomid,timepoint) values(v_roomid,v_start);
- insert ignore into tmp_time_point(roomid,timepoint) values(v_roomid,v_end);
- end if;
- until done end repeat;
- close cur_test;
- select roomid,date(s) dt,round(sum(timestampdiff(second,s,e))/60) ts,max(c) c from (
- select roomid,s,e ,count(distinct userid) c from (
- select distinct v6.roomid,v6.userid,greatest(s,starttime) s,least(e,endtime) e
- from (
- select distinct roomid,CAST(starttime as DATETIME) starttime,CAST(endtime as DATETIME) endtime from (
- select
- if(@roomid=roomid,@d,'') as starttime,@d:=timepoint,@roomid:=roomid,p.roomid,p.timepoint endtime
- from tmp_time_point p,(select @d:='',@roomid:=-1) vars
- order by roomid,timepoint
- ) v4 where starttime!='' and date(starttime)=date(endtime)
- ) v5 inner join t1 v6 on(v5.starttime between v6.s and v6.e and v5.endtime between v6.s and v6.e and v5.roomid=v6.roomid)
- ) v6 group by roomid,s,e having count(distinct userid)>1
- ) v7 group by roomid,date(s);
- END
都內聚到一個過程之後,不需要建立額外的普通表,直接在過程中建立臨時表.實現高內聚,低耦合.
call p
過程返回的結果即為最終結果.
三次測試耗時均低於 10.3秒
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-2150297/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Session重疊問題學習(三)--優化Session優化
- Session重疊問題學習(五)--最優化Session優化
- Session重疊問題學習(六)--極致優化Session優化
- Session重疊問題學習(一)Session
- Session重疊問題學習(八)--該問題第六次優化和Oracle版本Session優化Oracle
- Session重疊問題學習(九)--該問題第七次優化.優化合並演算法Session優化演算法
- Session重疊問題學習(七)--小花狸合併演算法和最後一次優化Session演算法優化
- MySQL優化學習手札(四) 單表訪問方法MySql優化
- webpack dll打包重複問題優化Web優化
- 再探強化學習強化學習
- Laravel 第四張學習——優化頁面(1)Laravel優化
- oracle performance tuning效能優化學習系列(四)OracleORM優化
- Shiro效能優化:解決Session頻繁讀寫問題優化Session
- 【強化學習】強化學習/增強學習/再勵學習介紹強化學習
- oracle performance tuning效能優化學習系列(四)_補OracleORM優化
- 凸優化問題優化
- 效能優化問題優化
- Laravel 第四章學習——優化頁面(2)Laravel優化
- 學習學習再學習
- 【調優】設計問題還是優化問題?優化
- 【OpenCV學習】計算兩幅影象的重疊區域OpenCV
- 強化學習-學習筆記11 | 解決高估問題強化學習筆記
- LayaAir引擎學習日誌14----LayaAir記憶體優化的問題AI記憶體優化
- 如何避開jquery動態繫結的事件重疊問題jQuery事件
- session共享問題???Session
- 斜率優化(凸包優化)DP問題acm優化ACM
- Fragment重影(重疊)白屏等問題原理解析,以及解決方案Fragment
- Android 百度地圖InfoWindow 出現重疊的問題Android地圖
- react 學習 問題React
- Tarjan再學習
- Oracle效能優化視訊學習筆記-資料庫配置和I/O問題Oracle優化筆記資料庫
- 03-凸優化問題優化
- 數值最優化—優化問題的解(二)優化
- 【MySQL】再說order by 優化MySql優化
- oracle 學習筆記---效能優化學習(1)Oracle筆記優化
- 再談優雅重試(retry)機制
- MySQL優化學習手札(三)MySql優化
- 斜率優化學習筆記優化筆記