zoukankan      html  css  js  c++  java
  • 关于查询优化

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

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

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

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

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

  • 相关阅读:
    iOS 关于使用xib创建cell的两种初始化方式
    KVO的初级使用
    通知的初级使用
    C语言的变量 常量
    C语言的编译 链接
    1 hello word
    java 中 == 与 equals引出的字符串比较
    02PSP0级及登陆界面开发
    00软工课程引言
    06动手动脑
  • 原文地址:https://www.cnblogs.com/jiqing9006/p/3224525.html
Copyright © 2011-2022 走看看