zoukankan      html  css  js  c++  java
  • 【DataBase】SQL优化案例:其一

    原始SQL:

    这里想做的事情就是查询一周的一个计算值

    可以理解为报表的那种

    主表 t_wechat_clue 生产库上200万数据量

    然后需要联表一些限制条件

    SELECT
    IFNULL(SUM((CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -6 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.follow_total ELSE 0 END)),0) AS y1,
    IFNULL(SUM((CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -5 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.follow_total ELSE 0 END)),0) AS y2,
    IFNULL(SUM((CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -4 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.follow_total ELSE 0 END)),0) AS y3,
    IFNULL(SUM((CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -3 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.follow_total ELSE 0 END)),0) AS y4,
    IFNULL(SUM((CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -2 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.follow_total ELSE 0 END)),0) AS y5,
    IFNULL(SUM((CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -1 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.follow_total ELSE 0 END)),0) AS y6,
    IFNULL(SUM((CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL 0 DAY)  AND HOUR(CLUE.gen_time) > HOUR(DATE_ADD(NOW(), INTERVAL -2 HOUR)) THEN CLUE.follow_total ELSE 0 END)),0) AS y7,
    
    IFNULL(SUM(DISTINCT CASE WHEN CLUE.org_code IS NOT NULL THEN (CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -6 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.dist_total ELSE 0 END) ELSE 0 END), 0) AS a1,
    IFNULL(SUM(DISTINCT CASE WHEN CLUE.org_code IS NOT NULL THEN (CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -5 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.dist_total ELSE 0 END) ELSE 0 END), 0) AS a2,
    IFNULL(SUM(DISTINCT CASE WHEN CLUE.org_code IS NOT NULL THEN (CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -4 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.dist_total ELSE 0 END) ELSE 0 END), 0) AS a3,
    IFNULL(SUM(DISTINCT CASE WHEN CLUE.org_code IS NOT NULL THEN (CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -3 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.dist_total ELSE 0 END) ELSE 0 END), 0) AS a4,
    IFNULL(SUM(DISTINCT CASE WHEN CLUE.org_code IS NOT NULL THEN (CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -2 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.dist_total ELSE 0 END) ELSE 0 END), 0) AS a5,
    IFNULL(SUM(DISTINCT CASE WHEN CLUE.org_code IS NOT NULL THEN (CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -1 DAY) AND HOUR(CLUE.gen_time) = 22 THEN CLUE.dist_total ELSE 0 END) ELSE 0 END), 0) AS a6,
    IFNULL(SUM(DISTINCT CASE WHEN CLUE.org_code IS NOT NULL THEN (CASE WHEN CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL 0 DAY)  AND HOUR(CLUE.gen_time) > HOUR(DATE_ADD(NOW(), INTERVAL -2 HOUR)) THEN CLUE.dist_total ELSE 0 END) ELSE 0 END), 0) AS a7
            FROM
    t_wechat_clues CLUE
    JOIN t_dms_member DMS_MEMBER ON CLUE.emp_id = DMS_MEMBER.employee_id AND LENGTH(CLUE.org_code)=8 AND SUBSTR(CLUE.org_code, 1, 1)='P'
    JOIN t_wechat_member WC_MEMBER ON DMS_MEMBER.wechat_emp_id = WC_MEMBER.userid AND WC_MEMBER.STATUS = 1 AND WC_MEMBER.TYPE = 2 
    JOIN (SELECT TT.id ,TT.NAME   FROM (
            WITH RECURSIVE cte AS(
                    SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
                    UNION ALL
                    SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
            ) SELECT id,NAME,parent_id FROM cte) TT ) TREE_ORG ON TREE_ORG.id = WC_MEMBER.department

    反正实际上数据返回到页面渲染Echarts花了10秒的样子

    经理说8行,必须要改动

    前提情况是,这里联表的字段和日期时间都做了索引处理

    慢的原因是查询的字段导致

    另外还有就是联表的字段数据类型需要一致

    不要让MySQL去推导转换,这会浪费一部分性能

    优化之后:

    随后同事给我一套UnionALL解法,虽然SQL很多,但是效率提升明显!

    SELECT
        IFNULL(SUM(CLUE.follow_total),0) AS y1 ,  
         SUM(DISTINCT (CASE WHEN  CLUE.org_code IS NOT NULL THEN CLUE.dist_total ELSE 0 END))  a1   
    FROM
    t_wechat_clues CLUE 
    JOIN t_dms_member DMS_MEMBER ON CLUE.emp_id = DMS_MEMBER.employee_id AND LENGTH(CLUE.org_code)=8 AND SUBSTR(CLUE.org_code, 1, 1)='P' 
     JOIN t_wechat_member WC_MEMBER ON DMS_MEMBER.wechat_emp_id = WC_MEMBER.userid  AND WC_MEMBER.STATUS = 1 AND WC_MEMBER.TYPE = 2 
     JOIN (SELECT TT.id ,TT.NAME   FROM (
            WITH RECURSIVE cte AS(
                    SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
                    UNION ALL
                    SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
            ) SELECT id,NAME,parent_id FROM cte) TT ) TREE_ORG ON TREE_ORG.id = WC_MEMBER.department 
      WHERE CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -6 DAY)  AND HOUR(CLUE.gen_time) = 22
      UNION ALL 
      
    SELECT
        IFNULL(SUM(CLUE.follow_total),0) AS y1 ,  
         SUM(DISTINCT (CASE WHEN  CLUE.org_code IS NOT NULL THEN CLUE.dist_total ELSE 0 END))  a1   
    FROM
    t_wechat_clues CLUE 
    JOIN t_dms_member DMS_MEMBER ON CLUE.emp_id = DMS_MEMBER.employee_id AND LENGTH(CLUE.org_code)=8 AND SUBSTR(CLUE.org_code, 1, 1)='P' 
     JOIN t_wechat_member WC_MEMBER ON DMS_MEMBER.wechat_emp_id = WC_MEMBER.userid  AND WC_MEMBER.STATUS = 1 AND WC_MEMBER.TYPE = 2 
     JOIN (SELECT TT.id ,TT.NAME   FROM (
            WITH RECURSIVE cte AS(
                    SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
                    UNION ALL
                    SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
            ) SELECT id,NAME,parent_id FROM cte) TT ) TREE_ORG ON TREE_ORG.id = WC_MEMBER.department 
      WHERE CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -5 DAY)  AND HOUR(CLUE.gen_time) = 22
      
        UNION ALL 
      
    SELECT
        IFNULL(SUM(CLUE.follow_total),0) AS y1 ,  
         SUM(DISTINCT (CASE WHEN  CLUE.org_code IS NOT NULL THEN CLUE.dist_total ELSE 0 END))  a1   
    FROM
    t_wechat_clues CLUE 
    JOIN t_dms_member DMS_MEMBER ON CLUE.emp_id = DMS_MEMBER.employee_id AND LENGTH(CLUE.org_code)=8 AND SUBSTR(CLUE.org_code, 1, 1)='P' 
     JOIN t_wechat_member WC_MEMBER ON DMS_MEMBER.wechat_emp_id = WC_MEMBER.userid  AND WC_MEMBER.STATUS = 1 AND WC_MEMBER.TYPE = 2 
     JOIN (SELECT TT.id ,TT.NAME   FROM (
            WITH RECURSIVE cte AS(
                    SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
                    UNION ALL
                    SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
            ) SELECT id,NAME,parent_id FROM cte) TT ) TREE_ORG ON TREE_ORG.id = WC_MEMBER.department 
      WHERE CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -4 DAY)  AND HOUR(CLUE.gen_time) = 22
      
        UNION ALL 
      
    SELECT
        IFNULL(SUM(CLUE.follow_total),0) AS y1 ,  
         SUM(DISTINCT (CASE WHEN  CLUE.org_code IS NOT NULL THEN CLUE.dist_total ELSE 0 END))  a1   
    FROM
    t_wechat_clues CLUE 
    JOIN t_dms_member DMS_MEMBER ON CLUE.emp_id = DMS_MEMBER.employee_id AND LENGTH(CLUE.org_code)=8 AND SUBSTR(CLUE.org_code, 1, 1)='P' 
     JOIN t_wechat_member WC_MEMBER ON DMS_MEMBER.wechat_emp_id = WC_MEMBER.userid  AND WC_MEMBER.STATUS = 1 AND WC_MEMBER.TYPE = 2 
     JOIN (SELECT TT.id ,TT.NAME   FROM (
            WITH RECURSIVE cte AS(
                    SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
                    UNION ALL
                    SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
            ) SELECT id,NAME,parent_id FROM cte) TT ) TREE_ORG ON TREE_ORG.id = WC_MEMBER.department 
      WHERE CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -3 DAY)  AND HOUR(CLUE.gen_time) = 22
      
        UNION ALL 
      
    SELECT
        IFNULL(SUM(CLUE.follow_total),0) AS y1 ,  
         SUM(DISTINCT (CASE WHEN  CLUE.org_code IS NOT NULL THEN CLUE.dist_total ELSE 0 END))  a1   
    FROM
    t_wechat_clues CLUE 
    JOIN t_dms_member DMS_MEMBER ON CLUE.emp_id = DMS_MEMBER.employee_id AND LENGTH(CLUE.org_code)=8 AND SUBSTR(CLUE.org_code, 1, 1)='P' 
     JOIN t_wechat_member WC_MEMBER ON DMS_MEMBER.wechat_emp_id = WC_MEMBER.userid  AND WC_MEMBER.STATUS = 1 AND WC_MEMBER.TYPE = 2 
     JOIN (SELECT TT.id ,TT.NAME   FROM (
            WITH RECURSIVE cte AS(
                    SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
                    UNION ALL
                    SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
            ) SELECT id,NAME,parent_id FROM cte) TT ) TREE_ORG ON TREE_ORG.id = WC_MEMBER.department 
      WHERE CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -2 DAY)  AND HOUR(CLUE.gen_time) = 22
      
        UNION ALL 
      
    SELECT
        IFNULL(SUM(CLUE.follow_total),0) AS y1 ,  
         SUM(DISTINCT (CASE WHEN  CLUE.org_code IS NOT NULL THEN CLUE.dist_total ELSE 0 END))  a1   
    FROM
    t_wechat_clues CLUE 
    JOIN t_dms_member DMS_MEMBER ON CLUE.emp_id = DMS_MEMBER.employee_id AND LENGTH(CLUE.org_code)=8 AND SUBSTR(CLUE.org_code, 1, 1)='P' 
     JOIN t_wechat_member WC_MEMBER ON DMS_MEMBER.wechat_emp_id = WC_MEMBER.userid  AND WC_MEMBER.STATUS = 1 AND WC_MEMBER.TYPE = 2 
     JOIN (SELECT TT.id ,TT.NAME   FROM (
            WITH RECURSIVE cte AS(
                    SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
                    UNION ALL
                    SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
            ) SELECT id,NAME,parent_id FROM cte) TT ) TREE_ORG ON TREE_ORG.id = WC_MEMBER.department 
      WHERE CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -1 DAY)  AND HOUR(CLUE.gen_time) = 22
      
        UNION ALL 
      
    SELECT
        IFNULL(SUM(CLUE.follow_total),0) AS y1 ,  
         SUM(DISTINCT (CASE WHEN  CLUE.org_code IS NOT NULL THEN CLUE.dist_total ELSE 0 END))  a1   
    FROM
    t_wechat_clues CLUE 
    JOIN t_dms_member DMS_MEMBER ON CLUE.emp_id = DMS_MEMBER.employee_id AND LENGTH(CLUE.org_code)=8 AND SUBSTR(CLUE.org_code, 1, 1)='P' 
     JOIN t_wechat_member WC_MEMBER ON DMS_MEMBER.wechat_emp_id = WC_MEMBER.userid  AND WC_MEMBER.STATUS = 1 AND WC_MEMBER.TYPE = 2 
     JOIN (SELECT TT.id ,TT.NAME   FROM (
            WITH RECURSIVE cte AS(
                    SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
                    UNION ALL
                    SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
            ) SELECT id,NAME,parent_id FROM cte) TT ) TREE_ORG ON TREE_ORG.id = WC_MEMBER.department 
      WHERE CLUE.gen_date = DATE_ADD(CURRENT_DATE,INTERVAL -0 DAY)  AND HOUR(CLUE.gen_time) > HOUR(DATE_ADD(NOW(), INTERVAL -2 HOUR))

    生产库执行结果是909ms 1秒差点就查完了

  • 相关阅读:
    easy ui 表单ajax和from两种提交数据方法
    easy ui 下拉级联效果 ,下拉框绑定数据select控件
    easy ui 下拉框绑定数据select控件
    easy ui 异步上传文件,跨域
    easy ui 菜单和按钮(Menu and Button)
    HTTP 错误 404.3
    EXTJS4.2 后台管理菜单栏
    HTML 背景图片自适应
    easy ui 表单元素input控件后面加说明(红色)
    EXTJS 4.2 添加滚动条
  • 原文地址:https://www.cnblogs.com/mindzone/p/15159309.html
Copyright © 2011-2022 走看看