• 关于查询优化


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

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

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

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

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

  • 相关阅读:
    VS2013使用scanf、gets及字符串函数编译报错error C4996: 'scanf': This function or variable may be unsafe. 原因及解决方案
    关于vs2013与office系列软件一起安装出现bug的情况描述以及解决办法——打开vs2013鼠标不动/动不了
    武汉华师驾校学车笔记_纪实
    vs2013由修改模式改为输入模式。
    解析:求最大公约数的“辗转相除法原理”
    关于scanf与scanf_s的区别,以及用scanf编译出错并且提示找不到可执行文件.exe的解决办法。
    [C编译器]在VS中编译调试C程序
    使用vs编译程序选择新建”空项目“与”win32控制台应用程序“的区别。
    AngularJS+Ionic开发-1.搭建开发环境
    PetaPoco源代码学习--3.Sql类
  • 原文地址:https://www.cnblogs.com/jiqing9006/p/3224525.html
Copyright © 2020-2023  润新知