发表于: 2017-04-04 23:53:13
2 1549
4月4日完成的事情:
1、花了两天时间把项目的代码改成符合java规范
4月5日计划的事情:
1、代码改的挺多地方,明天要结合前端页面重新调试了
收获:
见上两篇日报:再贴一遍
1、关于查询数据表中根据查询条件获取count,
现在的写法是:
List<Long> count = talentService.getIdsByDynamicCondition(Talent.class, param, 0, Integer.MAX_VALUE);
这种方式的问题在于性能,设置start为0,size为Integer.MAX_VALUE它会把符合条件的数据全部返回,而我们仅仅是需要统计符合条件的记录数,
之前对sql语句学习的不深,今天听老大讲才知道数据库中有专门统计个数的语句,后面就学了一下mysql中count用法,count(*)和count(列名)的执行效率问题
网上查到一些资料:
1.除非要统计某列非空值的总数,否则任何情况一律用COUNT(*),效率比COUNT(列名)高很多
2.除非有特殊需要,否则COUNT(*)不要加WHERE条件,会严重影响效率,如果加了条件COUNT(*)和COUNT(主键)效率是一致的,COUNT(非主键)效率很低
3.在没有WHERE条件的情况下:COUNT(*)等于COUNT(主键)优于COUNT(非主键有索引)优于COUNT(非主键无索引)
4.只要加了WHERE就会降低效率,即使是WHERE 1=1
不过在有WHERE限制条件的情况下,COUNT(*)会比COUNT(COL)快非常多;
项目中用到是动态查询符合条件的个数,即只需要统计主键也就是id的个数,所以COUNT(*)和COUNT(id)的效果也就是一样了,用COUNT(*)
动态拼接sql语句,修改DynamicUtil工具类getTalentList方法代码
方法参数增加一个isCount字段,count统计时传入true,查询ids时传入false,
这是相对select id的一种优化,其实count主要是用来统计数据量用于显示总页码,对于显示总页面,今天听老大提供了一个思路:
不允许使用select id的方式查询数据量,应该使用count查询得到总记录数
但是count查询也仍属性很耗性能的一种方式,一旦数据量很大的话就容易出问题。
这时要考虑的是用到缓存memcache,项目用到的dao中做了还多事情,其中一个count实现中有关于这部分内容:
如果缓存仍然不能满足需要时,就要考虑不显示总页码而只提供上一页和下一页操作,
最后当上一页下一页也满足不了的情况下老大给了一个判断是否有下一页的小技巧:
查询当前页数据时多查询一条数据,然后判断这条数据是否存在,如果存在,就说明有下一页,否则就没有下一页,这个小技巧挺妙的。
这是今天老大讲到的根据不同的数据量规模,系统要求的不同而采用不同的优化方案,而作为一个后端工程师要想往深处发展就必须性能和扩展问题,
查询count继续改进
查询count时并不需要排序,但是考虑到getIdsByDynamicCondition方法仍需要传入start和size参数,专门测试了一下sql语句后面拼接上limit start, size对count查询的影响:
1)拼接上limit 0, 5测试
结论:能正常查到结果
2)拼接上limit 5, 5测试:
结论:不能查询到结果,
说明count查询是如果后面拼接了limit,就不能有偏移值,或者把偏移值固定为0,而size对count其实是没影响的(我测试过了)因此controller中代码改进为:
这种写法也和别的项目相同。
2、打印日志问题
1)方法的入口处要把接收的参数打印出来,方面调试:
不管传入的参数有多复杂,最好都要用日志打印出来,这样和前端对接口时方便调试
2)判空操作是必要的,例如下面这个
通过id查到人才后,要对人才进行判空,因为并不能保证前端传递过来的id一定能查到人才。我这里如果判断为空后就打印一条日志:not get any talent,并返回前端该条信息
3)判空的正确使用方法
这种判空操作是不符合规范的,完全没有起到判空的作用,因为talent.getName()一旦空指针,if条件中并没有走到“==”后面程序就已经异常报错,这个属于java基础的内容了,当时写项目直接参考二期项目代码没有认真考虑,实在不该,正确的写法应该是:
3)判空的使用位置:
以删除人才信息接口为例:删除人才前需要先判断人才是否为上架状态,人才只有在下架状态才能被删除,在上架状态下删除要给出提示先下架后删除,并且,人才表有一个测评报告的附表,有些人才有测评报告有些人才没有,对于有测评报告的人才,删除人才信息后要相应的删除他的测评报告信息。
4)逻辑代码中避免出现为定义的常量
对于这个规范,我现在能想到的一个原因是,专门在一个类中定义一些代码中用到的常量,然后在其他用到地方引用,这样做的好处是,一旦要改变这些常量值,只需要在定义的地方改一处,其他地方也相应的改变了,不至于一处一处查找再一处一处修改,
我这里的做法是在相应的model实体类中定义这些常量,主要常量的名字最后见明知意
评论