博客
关于我
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一个表A中多个字段关联了表B的ID,如何关联查询?
    查看>>
    MYSQL一直显示正在启动
    查看>>
    MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
    查看>>
    MySQL万字总结!超详细!
    查看>>
    Mysql下载以及安装(新手入门,超详细)
    查看>>
    MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
    查看>>
    MySQL不同字符集及排序规则详解:业务场景下的最佳选
    查看>>
    Mysql不同官方版本对比
    查看>>
    MySQL与Informix数据库中的同义表创建:深入解析与比较
    查看>>
    mysql与mem_细说 MySQL 之 MEM_ROOT
    查看>>
    MySQL与Oracle的数据迁移注意事项,另附转换工具链接
    查看>>
    mysql丢失更新问题
    查看>>
    MySQL两千万数据优化&迁移
    查看>>
    MySql中 delimiter 详解
    查看>>
    MYSQL中 find_in_set() 函数用法详解
    查看>>
    MySQL中auto_increment有什么作用?(IT枫斗者)
    查看>>
    MySQL中B+Tree索引原理
    查看>>
    mysql中cast() 和convert()的用法讲解
    查看>>
    mysql中datetime与timestamp类型有什么区别
    查看>>
    MySQL中DQL语言的执行顺序
    查看>>