博客
关于我
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 interval显示条件值_MySQL INTERVAL关键字可以使用哪些不同的单位值?
    查看>>
    mysql problems
    查看>>
    MySQL replace函数替换字符串语句的用法(mysql字符串替换)
    查看>>
    mysql workbench6.3.5_MySQL Workbench
    查看>>
    MySQL Workbench安装教程以及菜单汉化
    查看>>
    MySQL Xtrabackup 安装、备份、恢复
    查看>>
    mysql [Err] 1436 - Thread stack overrun: 129464 bytes used of a 286720 byte stack, and 160000 bytes
    查看>>
    MySQL _ MySQL常用操作
    查看>>
    MySQL – 导出数据成csv
    查看>>
    MySQL —— 在CentOS9下安装MySQL
    查看>>
    mysql 不区分大小写
    查看>>
    mysql 两列互转
    查看>>
    MySQL 中开启二进制日志(Binlog)
    查看>>
    MySQL 中文问题
    查看>>
    MySQL 中日志的面试题总结
    查看>>
    MySQL 中随机抽样:order by rand limit 的替代方案
    查看>>
    MySQL 为什么需要两阶段提交?
    查看>>
    mysql 为某个字段的值加前缀、去掉前缀
    查看>>
    mysql 主从 lock_mysql 主从同步权限mysql 行锁的实现
    查看>>
    mysql 主从互备份_mysql互为主从实战设置详解及自动化备份(Centos7.2)
    查看>>