zoukankan      html  css  js  c++  java
  • 一个mysql比较典型的子查询改join优化

    一个mysql比较典型的子查询改join优化

    早些年当作sql server /orcal sql的dba,后来进入互联网用mysql比较高,早年各项目重度依赖sql

    近年几搞大数据,mysql也是用,不涉及优化,整体mysql在行业内是被弱化了的,因为针对各场景的其他sql/nosql组件可以选择

    量不大,不用优化,会读写就可以了。量大,换别的方案,而对sql的优化很少有像早期有专值的DBA 针对性的维护和操作

    最近业务方的数据慢查询提到了我这里,建议能不能抽空作点优化

    这又算是老本行了,就协助简单优化了一部分

    其实很多慢查询优化,说白了是mysql的问题,mysql的查询优化相比orcal和sql server 作的太差 不得不用一些很难看的技巧来适配mysql低下的处理能力

    表结构就不放了
    只放sql和查询计划

    重点是把子查询去掉,替换为join结构

    原始查询计划

    explain SELECT
    ed_set_interval, s.seed_set_status, s.creator_id, s.created_at, s.updated_at, s.expired_at, s.is_fulled, u.username, u.user_email d_set_platform, s.seed_set_price, s.se
        -> FROM
        -> sms_seed_set s
        -> LEFT JOIN sms_user u
        -> ON s.creator_id = u.id
        -> LEFT JOIN
        -> (SELECT sms_seed_set_id, count(*) AS count FROM sms_seed WHERE is_deleted = 'NO' GROUP BY sms_seed_set_id) AS ssc
        -> ON s.id = ssc.sms_seed_set_id
        -> WHERE ( s.is_deleted = 'NO' ) order by id desc LIMIT 20;
    +------+-------------+------------+--------+---------------+-------------------------+---------+-----------------------+---------+--------------------------+
    | id   | select_type | table      | type   | possible_keys | key                     | key_len | ref                   | rows    | Extra                    |
    +------+-------------+------------+--------+---------------+-------------------------+---------+-----------------------+---------+--------------------------+
    |    1 | PRIMARY     | s          | index  | NULL          | PRIMARY                 | 4       | NULL                  |       1 | Using where              |
    |    1 | PRIMARY     | u          | eq_ref | PRIMARY       | PRIMARY                 | 4       | sms_test.s.creator_id |       1 |                          |
    |    1 | PRIMARY     | <derived2> | ref    | key0          | key0                    | 5       | sms_test.s.id         |   14223 | Using where              |
    |    2 | DERIVED     | sms_seed   | index  | NULL          | idx_seed_set_is_deleted | 6       | NULL                  | 1422360 | Using where; Using index |
    +------+-------------+------------+--------+---------------+-------------------------+---------+-----------------------+---------+--------------------------+
    

    优化后

    explain SELECT ifnull(count(*),0) as seedCount,s.id, s.seed_set_source, s.seed_set_name, s.seed_set_description, s.seed_set_type, s.seed_set_platform, s.seed_set_price, s.seed_set_interval, s.seed_set_status, s.creator_id, s.created_at, s.updated_at, s.expired_at, s.is_fulled, u.username, u.user_email  FROM sms_seed ssc  LEFT JOIN sms_seed_set s ON ssc.sms_seed_set_id =s.id
    LEFT JOIN sms_user u ON s.creator_id = u.id 
    WHERE ( s.is_deleted = 'NO' and ssc.is_deleted = 'NO') 
    GROUP BY sms_seed_set_id order by s.id desc LIMIT 20;
    
    +------+-------------+-------+--------+-------------------------+-------------------------+---------+-----------------------+------+----------------------------------------------+
    | id   | select_type | table | type   | possible_keys           | key                     | key_len | ref                   | rows | Extra                                        |
    +------+-------------+-------+--------+-------------------------+-------------------------+---------+-----------------------+------+----------------------------------------------+
    |    1 | SIMPLE      | s     | ALL    | PRIMARY                 | NULL                    | NULL    | NULL                  |   21 | Using where; Using temporary; Using filesort |
    |    1 | SIMPLE      | u     | eq_ref | PRIMARY                 | PRIMARY                 | 4       | sms_test.s.creator_id |    1 |                                              |
    |    1 | SIMPLE      | ssc   | ref    | idx_seed_set_is_deleted | idx_seed_set_is_deleted | 6       | sms_test.s.id,const   | 4063 | Using where; Using index                     |
    +------+-------------+-------+--------+-------------------------+-------------------------+---------+-----------------------+------+----------------------------------------------+
    

    隐约记得mysql有个索引应用优先级的的问题,通过调整sql把大表的索引优先级调高,我习惯把大表提前

    从技术角度以上优化已经完成任务,但又要结合业务,业务对每个sql是有主副表的,要求再调下join几张表的先后顺序,把大表调后

    验证下调整table顺序后的查询计划是否变更,结果一致

    explain SELECT ifnull(count(*),0) as seedCount,s.id, s.seed_set_source, s.seed_set_name, s.seed_set_description, s.seed_set_type, s.seed_set_platform, s.seed_set_price, s.seed_set_interval, s.seed_set_status, s.creator_id, s.created_at, s.updated_at, s.expired_at, s.is_fulled, u.username, u.user_email  
    FROM sms_seed_set s  LEFT JOIN sms_seed ssc ON ssc.sms_seed_set_id =s.id
    LEFT JOIN sms_user u ON s.creator_id = u.id 
    WHERE ( s.is_deleted = 'NO' and ssc.is_deleted = 'NO') GROUP BY sms_seed_set_id order by s.id desc LIMIT 20;
    +------+-------------+-------+--------+-------------------------+-------------------------+---------+-----------------------+-------+----------------------------------------------+
    | id   | select_type | table | type   | possible_keys           | key                     | key_len | ref                   | rows  | Extra                                        |
    +------+-------------+-------+--------+-------------------------+-------------------------+---------+-----------------------+-------+----------------------------------------------+
    |    1 | SIMPLE      | s     | ALL    | PRIMARY                 | NULL                    | NULL    | NULL                  |    23 | Using where; Using temporary; Using filesort |
    |    1 | SIMPLE      | u     | eq_ref | PRIMARY                 | PRIMARY                 | 4       | sms_test.s.creator_id |     1 |                                              |
    |    1 | SIMPLE      | ssc   | ref    | idx_seed_set_is_deleted | idx_seed_set_is_deleted | 6       | sms_test.s.id,const   | 78177 | Using where; Using index                     |
    +------+-------------+-------+--------+-------------------------+-------------------------+---------+-----------------------+-------+----------------------------------------------+
    
  • 相关阅读:
    Delphi 打印纸张选项设置参数
    Windows win32 API 类库 硬件
    delphi 打印 PDevMode 说明
    Delphi GlobalAlloc、GlobalLock、GlobalUnlock、GlobalFree 函数
    delphi 设备函数GetDeviceCaps函数
    情感分析和数据集
    深度因式分解机
    因子分解机
    功能丰富的推荐系统
    序列感知推荐系统
  • 原文地址:https://www.cnblogs.com/zihunqingxin/p/14459812.html
Copyright © 2011-2022 走看看