博客
关于我
MySQL千万级多表关联SQL语句调优
阅读量:794 次
发布时间:2023-02-12

本文共 1845 字,大约阅读时间需要 6 分钟。

MySQL 表关联查询优化指南:基于实际业务场景的实践经验

在实际业务场景中,尤其是涉及千万级数据的关联查询优化时,使用EXPLAIN解析SQL语句并根据可能出现的优化需求进行调优至关重要。本文将从多个维度深入探讨如何优化关联查询性能,使查询在2秒内完成。


一、核心问题分析

在实际应用中,经常会遇到以下优化需求:

  • Using temporary:表关联时使用临时表进行排序,导致性能下降。
  • Using filesort:在分页操作时无法使用索引,直接影响查询效率。
  • Rows过多:查询结果集规模接近或超过表的总记录数。
  • Key为(Null):索引列存在空值,导致优化效果大打折扣。
  • possible_keys过多:索引候选项过多,难以选择最优索引。

  • 二、SQL优化实践

    1. 基于EXPLAIN的调优方法

    驱动表的确定
    • Nest Loop Join算法:MySQL默认使用Nest Loop Join算法,通过驱动表的结果集作为循环基础数据,逐条查询其他表。
    • EXPLAIN结果分析
      • 第一行显示的是驱动表。
      • 驱动表的选择标准:
      • 指定了联接条件的表为驱动表。
      • 未指定联接条件时,行数少的表为驱动表。
    优化目标
    • 减少Nested Loop循环次数。
    • 优先使用小结果集驱动大结果集
      • A JOIN B中,A为小结果集时,查询效率最高。
    Nested Loop Join特点
    • 逐条查询,属于高效的Nested Loop Join。
    • 若有第三个表参与,需通过前两个表的结果集作为基础数据,再次循环查询。

    三、两表JOIN优化

    1. 无ORDER BY条件

    • 使用LEFT JOIN、RIGHT JOIN或INNER JOIN即可。
    • 根据EXPLAIN结果选择最优Join类型。

    2. 有ORDER BY条件

    • 关键点
      • 若驱动表为a,效率最高,无需额外优化。
      • 若驱动表为b,需使用STRAIGHT_JOIN或LEFT JOIN且WHERE条件不含b的过滤。

    四、多表JOIN优化

    1. 无ORDER BY条件

    • 使用LEFT JOIN、RIGHT JOIN或INNER JOIN,根据实际情况选择。
    • 根据EXPLAIN结果进行优化。

    2. 有ORDER BY条件

    • 关键点
      • 所有Join必须为LEFT JOIN。
      • 每个Join字段需创建索引。
      • WHERE条件仅包含a表的条件,形成大表后过滤。

    五、常见误区

    1. 视图与JOIN的区别

    • 视图只是数据屏蔽机制,不影响JOIN性能。

    六、案例分析

    1. 使用STRAIGHT_JOIN优化

    SELECT c.*, r.HYPERVISOR_HOST_NAME hostname, r.HOST_IP FROM trust_monitor c STRAIGHT_JOIN res_node r ON c.res_node_id = r.ID STRAIGHT_JOIN am_assets a ON r.ASSET_ID = a.ID AND a.status = 58 STRAIGHT_JOIN se_role s ON a.DEPT_FLAG = s.ROLE_ORG AND s.ROLE_ID IN (32,33,36,41) WHERE c.STATUS = 58 AND c.changed_type = 79 LIMIT 1,10;

    2. 使用INNER JOIN优化

    SELECT c.*, r.HYPERVISOR_HOST_NAME hostname, r.HOST_IP FROM trust_monitor c INNER JOIN res_node r ON c.res_node_id = r.ID INNER JOIN am_assets a ON r.ASSET_ID = a.ID AND a.status = 58 INNER JOIN se_role s ON a.DEPT_FLAG = s.ROLE_ORG AND s.ROLE_ID IN (32,33,36,41) WHERE c.STATUS = 58 AND c.changed_time ORDER BY c.changed_time LIMIT 1,10;

    两者结果一致,性能表现相同。


    七、总结

    通过以上优化技巧,可以显著提升关联查询性能,避免临时表使用和文件排序的性能瓶颈。关键在于合理选择驱动表,优化Join类型和顺序,同时避免不必要的视图使用。

    转载地址:http://nmbfk.baihongyu.com/

    你可能感兴趣的文章
    Mysql中varchar类型数字排序不对踩坑记录
    查看>>
    mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
    查看>>
    MySQL中地理位置数据扩展geometry的使用心得
    查看>>
    Mysql中存储引擎简介、修改、查询、选择
    查看>>
    mysql中实现rownum,对结果进行排序
    查看>>
    mysql中对于数据库的基本操作
    查看>>
    mysql中的 +号 和 CONCAT(str1,str2,...)
    查看>>
    MySql中的concat()相关函数
    查看>>
    mysql中的concat函数,concat_ws函数,concat_group函数之间的区别
    查看>>
    MySQL中的count函数
    查看>>
    MySQL中的DB、DBMS、SQL
    查看>>
    MySQL中的DECIMAL类型:MYSQL_TYPE_DECIMAL与MYSQL_TYPE_NEWDECIMAL详解
    查看>>
    MySQL中的GROUP_CONCAT()函数详解与实战应用
    查看>>
    MySQL中的IO问题分析与优化
    查看>>
    MySQL中的ON DUPLICATE KEY UPDATE详解与应用
    查看>>
    mysql中的rbs,SharePoint RBS:即使启用了RBS,内容数据库也在不断增长
    查看>>
    mysql中的undo log、redo log 、binlog大致概要
    查看>>
    Mysql中的using
    查看>>
    MySQL中的关键字深入比较:UNION vs UNION ALL
    查看>>
    MYSQL中频繁的乱码问题终极解决
    查看>>