关于查询优化
公司有个需求,就是把有课的那个日期,用特殊的标记,标记出来。
我之前的思路是,每一个日期,都查询一次数据库,看看这一天是否有课,如果有课的话就加粗加下划线。
结果做出来了,但是效果很差,因为执行的时间太久了,都是用于执行数据库查询去了,很慢很慢。
数据库一共有三千多条数据,没执行一次查询用时约100ms作用,30次查询,大概要3秒钟左右,也就是说要等三秒才能一点一点的看到是否有课。这样用户体验就太不佳了。
耗时可以通过火狐来看,
这边可以查看,每一个异步请求所消耗的时间。
之前是请求,checkLessons三十次左右,每次都很长时间。
我试图减少一次查询时间的长度,我把一些关联查询都去除了,一些条件去除了,发现效果不大。总的查询时间还是很长。
后来,我转变了思路,只查询一次数据库,然后将所有的当月日期传递过去进行比较,这样只查询一次,一次的查询数据放入数组中,多次使用。这样就大大的提高的效率,用户体验也好多了。
在这个过程中也遇到很多问题,比如,如何将当月的日期都传递过去?
我尝试用json格式,其实也没必要,只要转化成字符串就可以了。
var date = ""; var year = $("#idCalendarYear").html(); var month = $("#idCalendarMonth").html(); $(".thisMonth").each(function(i){ //var $this = $(this); var day = $(this).text(); if(i==0){ date = year+"-"+month+"-"+day; }else{ date +="/"+ year+"-"+month+"-"+day; } });
上述代码,就是获取所用的日期,通过"/"来隔开的。
通过ajax传递到后台。
$.ajax({ type: "POST", url:"/default/index/ajax/do/checkLessons", data:"date="+date, success:function(response){ if(response){ var data = eval('('+response+')'); for(i in data)//遍历数组 { if(data[i]){ $(".thisMonth").eq(i-1).attr("style","font-weight:bold ;text-decoration: underline;"); } } } } });
后台对数据进行处理。
$date = $this->_request->getParam('date'); $arrdate = explode("/",$date); $whereLessons['lessons.school_id = ?'] = $this->identity->school_id; $whereLessons['lessons.grade = ?'] = $this->identity->grade; $whereLessons['lessons.user_id = ?'] = $this->identity->uid; $dao_lessons = new dao_lessons(); $aLessons = $dao_lessons->getLessons2($whereLessons);
后台获取date数据之后,通过explode,将其转变成数组数据,也就是这个月的所有日期。
查询出这个学校的,这个年级地 ,这个老师的相关课程数据,保存到数组$aLessons中,以供使用。
这样只用了一次查询,时间大大缩小了。
$arrflag = array(); foreach($arrdate as $key=>$day){ $t_min = strtotime($day); $t_max = strtotime($day . " 23:59:59"); foreach ($aLessons as $k=>$v){ if($t_min<=$v['startime']&&$t_max>=$v['endtime']){ $arrflag[$key+1] = 1; } } } $json = json_encode($arrflag); echo $json;
进行遍历查询,筛选,判断。有课的就保存到数组$arrflag中去,其中的key值,就对应了日期中的天。有课的那一天就会有值。
通过json来传递数据到前端。
if(response){ var data = eval('('+response+')'); for(i in data)//遍历数组 { if(data[i]){ $(".thisMonth").eq(i-1).attr("style","font-weight:bold ;text-decoration: underline;"); } } }
前端接到数据之后,进行处理,这里用到一个筛选技巧,就是eq(i-1),就是第几个元素,这里的i就是data的key值,也就是用课那一天。第一天,就是eq(0),第二天,就是eq(1)。第i天就是eq(i-1)。然后对其做一定的加粗加下划线处理。
这样就是达到效果了,只用查询一次数据库,大大的缩短了时间,提高了用户体验。
这是算法优化的一种吧!
换一个思路果然很不错的!
看看效果吧!
只用了94ms,就查询出了当月的有课内容。太棒了!
继续学习算法,优化算法,还是很有必要的。