中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Session重疊問題學習(四)--再優化

發布時間:2020-08-11 10:31:08 來源:ITPUB博客 閱讀:134 作者:壹頁書 欄目:MySQL數據庫
接前文:
需求描述和第一版解決方案(執行時間90秒)
http://blog.itpub.net/29254281/viewspace-2150229/

優化和修改bug的版本(執行時間25秒)
http://blog.itpub.net/29254281/viewspace-2150259/


我覺得在集合思維處理方式中,前文已經達到最優了.

如果放棄完全的集合處理思維,實際上還可以更加的優化.

前文的幾個問題.
1.引入了過多的表結構.
2.寫表本身也花費了時間.
3.前文按天批處理,粒度還是細了.應該一把批量全出最快.
4.前文計算最小間隔范圍的部分,因為應用集合化思維,不好理解性能還差.

前文計算最小間隔范圍的部分如下
  1. select roomid,as DATETIME) starttime,as DATETIME) endtime from (    
  2.      select @d as starttime,@d:=d,v3.roomid,v3.d endtime from (    
  3.                 select distinct roomid,     
  4.                 when nums.id=1 then v1s       
  5.                 when nums.id=2 then v1e       
  6.                 when nums.id=3 then v2s       
  7.                 when nums.id=4 then v2e       
  8.                 end d   from (    
  9.                     select   v1.roomid, v1.s v1s,v1.e v1e,v2.s v2s,v2.e v2e    
  10.                     from t1 v1    
  11.                     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)     
  12.                     where v2.roomid in(select distinct roomid from t1 where date(s)=pTime)    
  13.                     and v2.s>=pTime and v2.s<(pTime+interval '1' and (v2.roomid,v2.userid,v2.s,v2.e)!= (v1.roomid,v1.userid,v1.s,v1.e)     
  14.                 ) a,nums where nums.id<=4    
  15.                 order by roomid,d    
  16.     ) v3,(select @d:='') vars    
  17. ) v4 where starttime!='' 

該部分使用集合處理方式,不好理解性能還差.

這塊可以通過游標寫臨時表輕易解決。
本質上最小范圍就是
每天每個房間每個記錄的開始時間和結束時間都扣出來作為一行 排序。

然后找到每個時間最近的下一個時間,作為最小時間范圍.

如果使用游標,遍歷一遍即可.

  1. DELIMITER $$  
  2.   
  3. CREATE DEFINER=`root`@`localhost` PROCEDURE `p`()  
  4. BEGIN  
  5.     declare done int default 0;      
  6.     declare v_roomid bigint;  
  7.     declare v_start timestamp;  
  8.     declare v_end timestamp;  
  9.     declare cur_test CURSOR for select roomid,s,e from t1  ;  
  10.   
  11.     DECLARE  CONTINUE HANDLER FOR NOT FOUND  SET done = 1;      
  12.       
  13.     drop table if exists t1;  
  14.     drop table if exists tmp_time_point;  
  15.     CREATE temporary TABLE `t1` (  
  16.       `roomid` int(11) NOT NULL DEFAULT '0',  
  17.       `userid` bigint(20) NOT NULL DEFAULT '0',  
  18.       `s` timestamp NOT NULL DEFAULT ON UPDATE timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',  
  19.       primary KEY `roomid` (`roomid`,`s`,`e`,`userid`)  
  20.     ) ENGINE=InnoDB;  
  21.   
  22.     create temporary table tmp_time_point(  
  23.             roomid bigint,  
  24.             timepoint timestamp,  
  25.             primary key(roomid,timepoint)  
  26.     ) engine=memory;  
  27.   
  28.   
  29. insert into t1  
  30. select distinct    
  31. roomid,    
  32. userid,    
  33. if(date(s)!=date(e) and id>1,date(s+interval id-1 date(s+interval id-1 date(e) ,e,date_format(s+interval id-1 '%Y-%m-%d 23:59:59')) e    
  34. from (    
  35. SELECT DISTINCT s.roomid, s.userid, s.s, (      
  36.         SELECT MIN(e)      
  37.         FROM (SELECT DISTINCT roomid, userid, roomend AS e      
  38.             FROM u_room_log a      
  39.             WHERE NOT EXISTS (SELECT *      
  40.                 FROM u_room_log b      
  41.                 WHERE a.roomid = b.roomid      
  42.                     AND a.userid = b.userid      
  43.                     AND a.roomend >= b.roomstart      
  44.                     AND a.roomend < b.roomend)      
  45.             ) s2      
  46.         WHERE s2.e > s.s      
  47.             AND s.roomid = s2.roomid      
  48.             AND s.userid = s2.userid      
  49.         ) AS e      
  50. FROM (SELECT DISTINCT roomid, userid, roomstart AS s      
  51.     FROM u_room_log a      
  52.     WHERE NOT EXISTS (SELECT *      
  53.         FROM u_room_log b      
  54.         WHERE a.roomid = b.roomid      
  55.             AND a.userid = b.userid      
  56.             AND a.roomstart > b.roomstart      
  57.             AND a.roomstart <= b.roomend)      
  58.     ) s, (SELECT DISTINCT roomid, userid, roomend AS e      
  59.     FROM u_room_log a      
  60.     WHERE NOT EXISTS (SELECT *      
  61.         FROM u_room_log b      
  62.         WHERE a.roomid = b.roomid      
  63.             AND a.userid = b.userid      
  64.             AND a.roomend >= b.roomstart      
  65.             AND a.roomend < b.roomend)      
  66.     ) e      
  67. WHERE s.roomid = e.roomid      
  68.     AND s.userid = e.userid     
  69.     
  70. ) t1 ,    
  71. nums     
  72. where  nums.id<=datediff(e,s)+1    
  73. ;    
  74.   
  75.     open cur_test;      
  76.     repeat      
  77.         fetch cur_test into v_roomid, v_start,v_end;      
  78.         if done !=1 then    
  79.            insert ignore into tmp_time_point(roomid,timepoint) values(v_roomid,v_start);  
  80.            insert ignore into tmp_time_point(roomid,timepoint) values(v_roomid,v_end);  
  81.         end if;    
  82.     until done end repeat;      
  83.     close cur_test;   
  84.       
  85.     
  86.   
  87.    
  88. select roomid,date(s) dt,round(second,s,e))/60) ts,max(c) c from (       
  89.     select roomid,s,e ,distinct userid) c  from (  
  90.         select distinct v6.roomid,v6.userid,greatest(s,starttime) s,least(e,endtime) e  
  91.         from (  
  92.             select distinct roomid,as DATETIME) starttime,as DATETIME) endtime from (  
  93.                 select   
  94.                 if(@roomid=roomid,@d,'')  as starttime,@d:=timepoint,@roomid:=roomid,p.roomid,p.timepoint endtime  
  95.                 from tmp_time_point p,(select @d:='',@roomid:=-1) vars  
  96.                 order by roomid,timepoint  
  97.             ) v4 where starttime!='' and date(starttime)=date(endtime)  
  98.         ) 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)  
  99.     ) v6 group by roomid,s,e having distinct userid)>1     
  100. ) v7 group by roomid,date(s);  
  101.   
  102.   
  103. END  

都內聚到一個過程之后,不需要創建額外的普通表,直接在過程中創建臨時表.實現高內聚,低耦合.

call p 
過程返回的結果即為最終結果.

三次測試耗時均低于 10.3秒



向AI問一下細節

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

AI

舒兰市| 昌江| 尼勒克县| 牟定县| 班戈县| 门源| 宽城| 汉寿县| 丽水市| 宣化县| 湾仔区| 望江县| 永清县| 云阳县| 大兴区| 体育| 竹山县| 青海省| 福安市| 克东县| 怀柔区| 台东市| 武定县| 德昌县| 柳林县| 虹口区| 长汀县| 江达县| 高青县| 固原市| 寻乌县| 藁城市| 肃北| 浏阳市| 调兵山市| 青浦区| 松桃| 宁都县| 英吉沙县| 伽师县| 无锡市|