千家信息网

Session重叠问题学习(五)--最优化

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,周五晚上10点了.这一周连续优化Session合并和拆分问题.每天都比前一天提升性能一倍以上.终于在今天,用独创的小花狸Session合并算法达到了最优级别.令人振奋的1.5秒到2秒级别.时间已经很晚
千家信息网最后更新 2025年01月20日Session重叠问题学习(五)--最优化周五晚上10点了.
这一周连续优化Session合并和拆分问题.每天都比前一天提升性能一倍以上.
终于在今天,用独创的小花狸Session合并算法达到了最优级别.

令人振奋的1.5秒到2秒级别.

时间已经很晚了,思路也有些不清晰了.先把代码贴出来.下周再仔细解释一下这个奇妙算法。

  1. DELIMITER $$
  2. CREATE DEFINER=`root`@`localhost` PROCEDURE `p`()
  3. BEGIN
  4. declare done int default 0;
  5. declare v_roomid bigint;
  6. declare v_time timestamp(6);
  7. declare v_cur_type smallint;
  8. declare v_before_roomid bigint default -1;
  9. declare v_before_type smallint default -1;
  10. declare v_before_time timestamp(6) ;
  11. declare v_num bigint default 0;
  12. declare cur_test CURSOR for select roomid,type,timepoint from tmp_time_point order by roomid,timepoint,type ;
  13. DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  14. drop table if exists t1;
  15. drop table if exists t2;
  16. drop table if exists tmp_time_point;
  17. drop table if exists tmp_result;
  18. drop table if exists tmp_min_range;
  19. CREATE temporary TABLE `t1` (
  20. `roomid` int(11) NOT NULL DEFAULT '0',
  21. `userid` bigint(20) NOT NULL DEFAULT '0',
  22. `s` timestamp(6),
  23. `e` timestamp(6),
  24. primary KEY `roomid` (`roomid`,`s`,`e`,`userid`)
  25. ) ENGINE=memory;
  26. CREATE temporary TABLE `t2` (
  27. `roomid` int(11) NOT NULL DEFAULT '0',
  28. `s` timestamp(6),
  29. `e` timestamp(6),
  30. primary KEY `roomid` (`roomid`,`s`,`e`)
  31. ) ENGINE=memory;
  32. CREATE temporary TABLE `tmp_min_range` (
  33. `roomid` int(11) NOT NULL DEFAULT '0',
  34. `s` timestamp(6),
  35. `e` timestamp(6),
  36. primary KEY `roomid` (`roomid`,`s`,`e`),
  37. key(roomid,e)
  38. ) ENGINE=memory;
  39. create temporary table tmp_time_point(
  40. roomid bigint,
  41. timepoint timestamp(6),
  42. type smallint,
  43. key(roomid,timepoint)
  44. ) engine=memory;
  45. create temporary table tmp_result(
  46. roomid bigint,
  47. timepoint timestamp(6),
  48. c int
  49. ) engine=memory;
  50. SET @A=0;
  51. SET @B=0;
  52. insert into t1(roomid,userid,s,e)
  53. select distinct
  54. roomid, userid,
  55. 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
  56. from (
  57. SELECT x.roomid,x.userid,s,e
  58. FROM
  59. (
  60. (
  61. SELECT @B:=@B+1 AS id,roomid,userid,s
  62. FROM (
  63. SELECT DISTINCT roomid, userid, roomstart AS s
  64. FROM u_room_log a
  65. WHERE NOT EXISTS (SELECT *
  66. FROM u_room_log b
  67. WHERE a.roomid = b.roomid
  68. AND a.userid = b.userid
  69. AND a.roomstart > b.roomstart
  70. AND a.roomstart <= b.roomend)
  71. ) AS p
  72. ) AS x,
  73. (
  74. SELECT @A:=@A+1 AS id,roomid,userid,e
  75. FROM
  76. (
  77. SELECT DISTINCT roomid, userid, roomend AS e
  78. FROM u_room_log a
  79. WHERE NOT EXISTS (SELECT *
  80. FROM u_room_log b
  81. WHERE a.roomid = b.roomid
  82. AND a.userid = b.userid
  83. AND a.roomend >= b.roomstart
  84. AND a.roomend < b.roomend)
  85. ) AS o
  86. ) AS y
  87. )
  88. WHERE x.id = y.id AND x.roomid = y.roomid AND x.userid = y.userid
  89. ) t1 ,
  90. nums
  91. where nums.id<=datediff(e,s)+1
  92. ;
  93. insert into t2 (roomid,s,e)
  94. select roomid,
  95. s+interval startnum/1000000 second s,
  96. e-interval endnum/1000000 second e
  97. from (
  98. select
  99. roomid,
  100. s,e,
  101. startnum,
  102. when @eflag=eflag then @rn:=@rn+1 when @eflag:=eflag then @rn else @rn end endnum
  103. from (
  104. select * from (
  105. select when @sflag=sflag then @rn:=@rn+1 when @sflag:=sflag then @rn else @rn end startnum,roomid,s,e,sflag,eflag from
  106. (
  107. select * from
  108. (
  109. select t1.*,concat('[',roomid,'],',s) sflag,concat('[',roomid,'],',e) eflag from t1 order by roomid ,sflag
  110. )a,(select @sflag:='',@rn:=0,@eflag:='') vars
  111. ) b
  112. ) bb order by roomid,eflag
  113. ) c
  114. ) d ;
  115. insert into tmp_time_point(roomid,timepoint,type) select roomid,s,1 from t2;
  116. insert into tmp_time_point(roomid,timepoint,type) select roomid,e,0 from t2;
  117. insert into tmp_min_range(roomid,s,e)
  118. select distinct roomid,starttime starttime, endtime endtime from (
  119. select
  120. if(@roomid=roomid,@d,'') as starttime,@d:=str_to_date(timepoint,'%Y-%m-%d %H:%i:%s.%f'),@roomid:=roomid,p.roomid,str_to_date(timepoint,'%Y-%m-%d %H:%i:%s.%f') endtime
  121. from tmp_time_point p,(select @d:='',@roomid:=-1) vars
  122. order by roomid,timepoint
  123. ) v4 where starttime!='' and date(starttime)=date(endtime);
  124. open cur_test;
  125. repeat
  126. fetch cur_test into v_roomid,v_cur_type,v_time;
  127. if done !=1 then
  128. -- 第一行或者每个房间的第一行
  129. if v_before_roomid=-1 or v_roomid!=v_before_roomid then
  130. set v_before_roomid:=v_roomid;
  131. set v_before_type:=1;
  132. set v_before_time:='0000-00-00 00:00:00';
  133. set v_num:=0;
  134. end if;
  135. if v_before_type=1 then
  136. set v_num:=v_num+1;
  137. insert into tmp_result(roomid,timepoint,c) values(v_roomid,v_time,v_num);
  138. end if;
  139. if v_before_type=0 then
  140. set v_num:=v_num-1;
  141. insert into tmp_result(roomid,timepoint,c) values(v_roomid,v_time,v_num);
  142. end if;
  143. set v_before_roomid:=v_roomid;
  144. set v_before_type:=v_cur_type;
  145. set v_before_time:=v_time;
  146. end if;
  147. until done end repeat;
  148. close cur_test;
  149. select roomid,date(s) dt,round(second,date_format(s,'%Y-%m-%d %H:%i:%s'),date_format(e,'%Y-%m-%d %H:%i:%s')))/60) ts,max(c)-1 c from (
  150. select a.roomid,a.s,a.e,r.c,r.timepoint from tmp_result r
  151. inner join
  152. tmp_min_range a on( r.timepoint=a.e and r.roomid=a.roomid)
  153. where c>2
  154. ) a group by roomid,date(s);
  155. END

和之前的算法比较,结果一致。基本上都在1.6秒左右.
0