关于查询优化

公司有个需求,就是把有课的那个日期,用特殊的标记,标记出来。

我之前的思路是,每一个日期,都查询一次数据库,看看这一天是否有课,如果有课的话就加粗加下划线。

结果做出来了,但是效果很差,因为执行的时间太久了,都是用于执行数据库查询去了,很慢很慢。

数据库一共有三千多条数据,没执行一次查询用时约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,就查询出了当月的有课内容。太棒了!

继续学习算法,优化算法,还是很有必要的。

posted @ 2013-07-30 10:21  TBHacker  阅读(369)  评论(0编辑  收藏  举报