博客
关于我
MySQL千万级多表关联SQL语句调优
阅读量:789 次
发布时间: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 触发器
    查看>>
    mysql 让所有IP访问数据库
    查看>>
    mysql 记录的增删改查
    查看>>
    MySQL 设置数据库的隔离级别
    查看>>
    MySQL 证明为什么用limit时,offset很大会影响性能
    查看>>
    Mysql 语句操作索引SQL语句
    查看>>
    MySQL 调优/优化的 101 个建议!
    查看>>
    mysql 转义字符用法_MySql 转义字符的使用说明
    查看>>
    mysql 输入密码秒退
    查看>>
    mysql 递归查找父节点_MySQL递归查询树状表的子节点、父节点具体实现
    查看>>
    mysql 里对root及普通用户赋权及更改密码的一些命令
    查看>>
    Mysql 重置自增列的开始序号
    查看>>
    MySQL 高可用性之keepalived+mysql双主
    查看>>
    mysql-connector-java各种版本下载地址
    查看>>
    mysql-group_concat
    查看>>
    MySQL-【4】基本操作
    查看>>
    Mysql-丢失更新
    查看>>
    Mysql-事务阻塞
    查看>>
    Mysql-存储引擎
    查看>>
    MySQL-数据目录
    查看>>