当前位置:   article > 正文

mysql derived2、Using temporary 和 Using filesort 优化记录_derived2如何优化

derived2如何优化

-- 业务每周查询一份报表,每次执行sql磁盘直接由49%涨到%93,执行了几次发现是sql用到了磁盘临时表,对sql进行了改写
-- 原查询sql:

  1. SELECT
  2.     CODE,
  3.     NAME,
  4.     num,
  5.     GROUP_CONCAT(product_id) AS product_ids,
  6.     GROUP_CONCAT(product_name) AS product_names
  7. FROM
  8.     (SELECT
  9.         COUNT(DISTINCT (psn.Psnid)) AS num,
  10.             cus.CODE,
  11.             cus.`name`,
  12.             od.product_id,
  13.             pr.NAME AS product_name
  14.     FROM
  15.         mid_psn_copy AS psn
  16.     JOIN customer AS cus ON cus.CODE = psn.PkCorp
  17.     JOIN product_order_rel AS od ON od.customer_code = cus.CODE
  18.     JOIN product AS pr ON pr.id = od.product_id
  19.     WHERE
  20.         psn.`Status` = 1 AND od.`status` = 1
  21.     GROUP BY od.customer_code , od.product_id) AS tt
  22. GROUP BY CODE;
  23.         
  24. -- 69 rows in set, 1 warning (34.54 sec)

-- 原执行计划 

  1. +----+-------------+------------+--------+---------------------------------------------------------------------------+------------------------------+---------+------------------------+--------+----------------------------------------------+
  2. | id | select_type | table      | type   | possible_keys                                                             | key                          | key_len | ref                    | rows   | Extra                                        |
  3. +----+-------------+------------+--------+---------------------------------------------------------------------------+------------------------------+---------+------------------------+--------+----------------------------------------------+
  4. |  1 | PRIMARY     | <derived2> | ALL    | NULL                                                                      | NULL                         | NULL    | NULL                   | 325296 | Using filesort                               |
  5. |  2 | DERIVED     | cus        | index  | idx_custom_code,idx_code_name                                             | idx_code_name                | 274     | NULL                   |    251 | Using index; Using temporary; Using filesort |
  6. |  2 | DERIVED     | psn        | ref    | idx_psn_pkcorp,idx_psn_Status,idx_pkcrop_status                           | idx_pkcrop_status            | 157     | gmcloud.cus.code,const |     36 | Using index condition                        |
  7. |  2 | DERIVED     | od         | ref    | idx_customer_code_pdid_status,idx_product_id,idx_customer_code_product_id | idx_customer_code_product_id | 123     | gmcloud.cus.code       |     36 | Using where; Using index                     |
  8. |  2 | DERIVED     | pr         | eq_ref | PRIMARY                                                                   | PRIMARY                      | 8       | gmcloud.od.product_id  |      1 | NULL                                         |
  9. +----+-------------+------------+--------+---------------------------------------------------------------------------+------------------------------+---------+------------------------+--------+----------------------------------------------+ 

 

-- 第一次优化,去掉外层嵌套,把外层条件融合到当前sql
-- 加联合索引
-- alter table customer add key idx_code_name (`code`,`name`)
-- alter table product_order_rel add key idx_customer_code_pdid_status (`customer_code`,`product_id`,`status`)

  1. SELECT
  2.         COUNT(DISTINCT (psn.Psnid)) AS num,
  3.             cus.CODE,
  4.             cus.`name`,
  5.             GROUP_CONCAT(od.product_id) AS product_ids,
  6.             GROUP_CONCAT(pr.NAME) AS product_names
  7.     FROM
  8.         mid_psn_copy AS psn
  9.     JOIN customer AS cus ON cus.CODE = psn.PkCorp
  10.     JOIN product_order_rel AS od ON od.customer_code = cus.CODE
  11.     JOIN product AS pr ON pr.id = od.product_id
  12.     WHERE
  13.         psn.`Status` = 1 AND od.`status` = 1
  14.     GROUP BY cus.CODE, od.customer_code , od.product_id;

-- 查看执行计划,虽然没有了DERIVED、derived2,但是看到还有Using temporary; Using filesort存在

  1. +----+-------------+-------+--------+-------------------------------+-------------------------------+---------+-----------------------+------+----------------------------------------------+
  2. | id | select_type | table | type   | possible_keys                 | key                           | key_len | ref                   | rows | Extra                                        |
  3. +----+-------------+-------+--------+-------------------------------+-------------------------------+---------+-----------------------+------+----------------------------------------------+
  4. |  1 | SIMPLE      | cus   | index  | idx_custom_code,idx_code_name | idx_code_name                 | 274     | NULL                  |  251 | Using index; Using temporary; Using filesort |
  5. |  1 | SIMPLE      | psn   | ref    | idx_psn_pkcorp,idx_psn_Status | idx_psn_pkcorp                | 152     | gmcloud.cus.code      |   69 | Using index condition; Using where           |
  6. |  1 | SIMPLE      | od    | ref    | idx_customer_code_pdid_status | idx_customer_code_pdid_status | 123     | gmcloud.cus.code      |   36 | Using where; Using index                     |
  7. |  1 | SIMPLE      | pr    | eq_ref | PRIMARY                       | PRIMARY                       | 8       | gmcloud.od.product_id |    1 | NULL                                         |
  8. +----+-------------+-------+--------+-------------------------------+-------------------------------+---------+-----------------------+------+----------------------------------------------+ 

-- 第二次优化,把group by 后边的od.customer_code , od.product_id去掉,在前边group_concat加上distinct    
-- 在where条件和group by条件都加了联合索引
-- alter table customer add key idx_code_name (`code`,`name`)
-- alter table mid_psn_copy add key idx_pkcrop_status` (`PkCorp`,`Status`)
-- alter table product_order_rel add key idx_customer_code_product_id (`customer_code`,`product_id`,`status`)
-- 优化完的sql:

  1. SELECT
  2.         COUNT(DISTINCT (psn.Psnid)) AS num,
  3.         cus.CODE,
  4.         cus.`name`,
  5.         GROUP_CONCAT(distinct od.product_id) AS product_ids,
  6.         GROUP_CONCAT(distinct pr.NAME) AS product_names
  7.     FROM
  8.         customer AS cus
  9.     JOIN product_order_rel AS od ON od.customer_code = cus.CODE
  10.     JOIN mid_psn_copy AS psn ON  psn.PkCorp = cus.CODE
  11.     JOIN product AS pr ON pr.id = od.product_id
  12.     WHERE
  13.         psn.`Status` = 1 AND od.`status` = 1
  14.     GROUP BY cus.CODE;

-- 再次查看执行计划

  1. +----+-------------+-------+--------+-------------------------------------------------+------------------------------+---------+------------------------+------+--------------------------+
  2. | id | select_type | table | type   | possible_keys                                   | key                          | key_len | ref                    | rows | Extra                    |
  3. +----+-------------+-------+--------+-------------------------------------------------+------------------------------+---------+------------------------+------+--------------------------+
  4. |  1 | SIMPLE      | cus   | index  | idx_code_name,idx_code                          | idx_code_name                | 274     | NULL                   |  251 | Using index              |
  5. |  1 | SIMPLE      | psn   | ref    | idx_psn_pkcorp,idx_psn_Status,idx_pkcrop_status | idx_pkcrop_status            | 157     | gmcloud.cus.code,const |   36 | Using index condition    |
  6. |  1 | SIMPLE      | od    | ref    | idx_product_id,idx_customer_code_product_id     | idx_customer_code_product_id | 123     | gmcloud.cus.code       |   36 | Using where; Using index |
  7. |  1 | SIMPLE      | pr    | eq_ref | PRIMARY                                         | PRIMARY                      | 8       | gmcloud.od.product_id  |    1 | NULL                     |
  8. +----+-------------+-------+--------+-------------------------------------------------+------------------------------+---------+------------------------+------+--------------------------+

-- 调整下表头顺序

  1. SELECT
  2.     cus.CODE,
  3.     cus.`name`,
  4.     COUNT(DISTINCT (psn.Psnid)) AS num,
  5.     GROUP_CONCAT(DISTINCT od.product_id) AS product_ids,
  6.     GROUP_CONCAT(DISTINCT pr.NAME) AS product_names
  7. FROM
  8.     customer AS cus
  9.         JOIN
  10.     product_order_rel AS od ON od.customer_code = cus.CODE
  11.         JOIN
  12.     mid_psn_copy AS psn ON psn.PkCorp = cus.CODE
  13.         JOIN
  14.     product AS pr ON pr.id = od.product_id
  15. WHERE
  16.     psn.`Status` = 1 AND od.`status` = 1
  17. GROUP BY cus.CODE;
  18. -- 69 rows in set (6.95 sec)

-- 执行sql后,查看临时表状态没有增加了
mysql> show status like '%tmp%';

  1. +-------------------------+-------+
  2. | Variable_name           | Value |
  3. +-------------------------+-------+
  4. | Created_tmp_disk_tables | 0     |
  5. | Created_tmp_files       | 619   |
  6. | Created_tmp_tables      | 3     |
  7. +-------------------------+-------+


    
优化待续。。。
    
    
       
    
    
    
   

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/1006626
推荐阅读
相关标签
  

闽ICP备14008679号