记录最近优化统计sql学到的东西

  1. sql优化要先拉取需要优化的语句放入数据库,用expalin查看运行计划,看是否走了索引,如果没有走,查看自己的语句分析没有走索引的原因,并进行语句修改。
  2. 可以用System.currentTimeMillis()来判断查询语句和for循环的使用时间。
  3. map的使用,把数据库查询出来的结果封装到map,在通过map.get(key)拿到value值,以此减少循环中和数据库交互的情况。


  • 由于在双重for循环使用了数据库交互,导致时间较长优化

优化方案:抽出与数据库交互的部分,用map来封装查询结果,取得时候从map中获取需要的值。

本次优化有两个难点:

  • 将普通查询结果封装到map
  • 查出来的结果做sum汇总

解决展示:1.将普通查询结果封装到map ,查出所有模板编码以及对应名称,数据库查询语句:

SELECT DISTINCT a.template_code templateCode,a.template_name templateName from message_template a 

数据库结果展示:

 

mapper.xml层封装(返回的是list<map<string,string>>),resultType用java.util.Map:

 <!--获取所有机构和机构名称 -->
    <select id="getdeptCodeAndName"
            resultType="java.util.Map">
            SELECT DISTINCT a.dept_id deptId,a.`name` deptName from sys_dept a
	</select>

mapper层封装:

 /**
     * 获取所有服务编码和服务名称
     * @return
     */
    List<Map<Integer,String>> getdeptCodeAndName();

实现类impl调用

        //获取全部模板和名称封装到map
        List<Map<String, String>> templateCodeAndNameList = countMapper.getTemplateCodeAndName();
        Map<String, String> getTemplateNameMap = new HashMap<>();
        for (Map<String, String> stringStringMap : templateCodeAndNameList) {
            getTemplateNameMap.put(stringStringMap.get("templateCode"),stringStringMap.get("templateName"));
        }

封装好的map使用

//上面是数据库交互,下面是直接从map中获取
//   sendStaticResp.setTemplateCode(countMapper.getTemplateName(templateCode));
      sendStaticResp.setTemplateCode(getTemplateNameMap.get(templateCode));

2.查出来的结果做sum汇总 :每个服务中每个机构的发送总数  ,数据库查询语句:

SELECT 
  sum(a.total_num) total ,a.dept_id deptId,a.template_code templateCode
FROM 
send_static_info a
GROUP BY a.dept_id,a.template_code;

查询结果:

 mapper.xml层封装(返回的是一个封装的对象,字段有templateCode,deptId,total):

<!--查出所有所有服务中所有机构对应的发送总数 -->
	<select id="getALLCount"
		resultType="com.sinosoft.liscloud.sms.api.vo.SendStaticSumResp">
        SELECT
         sum(a.total_num) total ,a.dept_id deptId,a.template_code templateCode
        FROM
        send_static_info a
        GROUP BY a.dept_id,a.template_code;
	</select>

mapper层封装:

/**
     * 查出所有所有服务中所有机构对应的发送总数
     * @return
     */
    List<SendStaticSumResp> getALLCount();

实现类impl调用:期间使用了System.currentTimeMillis()来判断查询语句和for循环的使用时间,

将查询结果封装到了两个map,getTotalMap封装了机构编号+服务编码,保证map中的key的唯一,外层循环为了查询不重复的服务编码,内层循环机构编码,在内层循环时通过传入的编码和机构编码,获取到查询结果中的total数,getSumTotalMap主要是做汇总使用,传入机构编码,为空直接从结果集获取total数,不为空从getTotalMap中通过机构编码查出来总数追加

  //查出所有所有服务中所有机构对应的发送总数
        List<SendStaticSumResp> sumList = new ArrayList<>();
        long l = System.currentTimeMillis();
        sumList = countMapper.getALLCount();
        long l2 = System.currentTimeMillis();
        System.out.println("查询语句-----------------------------------"+ (l2-l) );


        //将k和总数封装以及k和部门名称封装到不同的map中
        Map<String, Integer> getTotalMap = new HashMap<>();
        Map<String, Integer> getSumTotalMap = new HashMap<>();
        long currentTimeMillis = System.currentTimeMillis();
        for (SendStaticSumResp sendStaticSumResp : sumList) {
            if (sendStaticSumResp.getDeptId()==null){
                sendStaticSumResp.setDeptId("");
            }
            if (sendStaticSumResp.getTemplateCode() ==null){
                sendStaticSumResp.setTemplateCode("");
            }
            getTotalMap.put(sendStaticSumResp.getDeptId()+sendStaticSumResp.getTemplateCode(),sendStaticSumResp.getTotal());
            getSumTotalMap.put(sendStaticSumResp.getDeptId(),
                    getSumTotalMap.get(sendStaticSumResp.getDeptId())==null? sendStaticSumResp.getTotal()
                    : sendStaticSumResp.getTotal()+getSumTotalMap.get(sendStaticSumResp.getDeptId()) );
        }
        long currentTimeMillis2 = System.currentTimeMillis();
        System.out.println("查询for循环-----------------------------------"+(currentTimeMillis2-currentTimeMillis));

使用map

 if ("sum".equals(templateCode)){
                	templateCode = null;
                    sendStaticResp.setTemplateCode("汇总");
                    for(int i=0;i<deptIdList.size();i++) {
                    	String sumDeptId = deptIdList.get(i);
//                     	Integer sumTotal = countMapper.getCount(sumDeptId,templateCode);
                        Integer sumTotal= getSumTotalMap.get(sumDeptId);

                     	if(sumTotal ==null) {
                     		sumTotal=0;
                     	}






else {
                     for (int i=0;i<deptIdList.size();i++) {
                     	String deptId = deptIdList.get(i);
//                         String deptName = countMapper.getDeptName(deptId);
                         String deptName = getDeptNameMap.get(deptId);
                     	Integer total = 0;
                         Map<String, Integer> deptCount = new HashMap<>();

//                         total = countMapper.getCount(deptId, templateCode);
                          total =  getTotalMap.get(deptId+templateCode);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值