博客
关于我
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分组查询
    查看>>
    Mysql分表后同结构不同名称表之间复制数据以及Update语句只更新日期加减不更改时间
    查看>>
    mySql分页Iimit优化
    查看>>
    MySQL分页查询
    查看>>
    mysql列转行函数是什么
    查看>>
    mysql创建函数报错_mysql在创建存储函数时报错
    查看>>
    mysql创建数据库和用户 并授权
    查看>>
    mysql创建数据库指定字符集
    查看>>
    MySql创建数据表
    查看>>
    MySQL创建新用户以及ERROR 1396 (HY000)问题解决
    查看>>
    MySQL创建用户与授权
    查看>>
    MySQL创建用户报错:ERROR 1396 (HY000): Operation CREATE USER failed for 'slave'@'%'
    查看>>
    MySQL创建索引时提示“Specified key was too long; max key length is 767 bytes”
    查看>>
    mysql初始密码错误问题
    查看>>
    mysql判断某一张表是否存在的sql语句以及方法
    查看>>
    mysql加入安装策略_一键安装mysql5.7及密码策略修改方法
    查看>>
    mysql加强(1)~用户权限介绍、分别使用客户端工具和命令来创建用户和分配权限
    查看>>
    mysql加强(3)~分组(统计)查询
    查看>>
    mysql加强(4)~多表查询:笛卡尔积、消除笛卡尔积操作(等值、非等值连接),内连接(隐式连接、显示连接)、外连接、自连接
    查看>>
    mysql加强(5)~DML 增删改操作和 DQL 查询操作
    查看>>