MySQL的驱动表和被驱动表

        在 MySQL 查询执行过程中,涉及到多表关联操作时,驱动表(Driving Table)和 被驱动表(Driven Table)是重要的概念。理解这两个概念对优化查询性能至关重要。驱动表是查询执行过程中首先扫描的表,被驱动表是随后与驱动表进行关联的表。选择合适的驱动表可以显著提高查询性能,反之则可能导致查询性能下降。

        为了详细解释驱动表和被驱动表的工作原理,我们将从以下几个方面进行分析:

1. 驱动表和被驱动表的定义

  • 驱动表(Driving Table):在多表连接查询中,MySQL 会首先扫描的表称为驱动表。驱动表的每一行数据都需要与被驱动表中的数据进行匹配,以生成最终的结果集。

  • 被驱动表(Driven Table):驱动表扫描完成后,MySQL 会将驱动表中的每一行与被驱动表中的数据进行关联。被驱动表通常是根据驱动表的结果进一步进行过滤的表。

举个简单的例子:

SELECT * FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE e.salary > 5000;

        在这个查询中,employees 表和 departments 表通过 department_id 进行关联。MySQL 执行查询时会选择其中一个表作为驱动表,另一个表作为被驱动表。通常情况下,驱动表会是小表或者经过过滤条件限制行数的表。


2. 驱动表和被驱动表的选择策略

        MySQL 优化器在处理多表查询时,会根据以下几个因素来选择驱动表和被驱动表:

2.1 表的大小

        通常,MySQL 会优先选择较小的表作为驱动表。这样可以减少扫描表时的 I/O 操作和数据量,并且在驱动表中的每一行去被驱动表中寻找匹配数据时,可以避免大量无效的数据匹配。

2.2 表的过滤条件

        过滤条件(WHERE 子句或 JOIN 条件)越严格,筛选出的数据行数越少。通常,MySQL 会选择那些在查询初期就可以大幅度减少结果集大小的表作为驱动表。因为如果驱动表筛选出的行数较少,后续与被驱动表的关联操作的开销也会降低。

2.3 索引的使用

        如果某张表上有良好的索引,MySQL 可能会优先选择该表作为驱动表。通过索引扫描,MySQL 能更高效地访问记录,减少全表扫描的开销。

2.4 关联条件

        MySQL 优化器还会根据表与表之间的关联条件选择驱动表。关联条件越高效(如使用主键或唯一索引),被驱动表的查询效率越高,因此 MySQL 可能会倾向于选择与这种高效关联的表作为被驱动表。


3. MySQL 执行计划中的驱动表和被驱动表

        MySQL 使用 基于成本的优化器(Cost-Based Optimizer, CBO),它会基于表的大小、索引使用情况、过滤条件等信息,选择合适的驱动表和被驱动表。在执行查询时,优化器会生成执行计划并通过 EXPLAIN 命令来展示驱动表和被驱动表的选择情况。

3.1 通过 EXPLAIN 查看驱动表和被驱动表

        可以使用 EXPLAIN 来查看 MySQL 的执行计划,帮助判断哪个表是驱动表,哪个表是被驱动表。

EXPLAIN SELECT * FROM employees e JOIN departments d ON e.department_id = d.id WHERE e.salary > 5000;

        执行该 EXPLAIN 命令后,MySQL 会展示每个表的扫描顺序,以及每个表的访问方法(如全表扫描、索引扫描等)。通常,第一个出现的表是驱动表,之后的表则是被驱动表。

 

        从上述结果中可以看到,employees 表是驱动表,因为它在执行计划中的顺序靠前,并且它通过索引过滤部分数据后再去关联 departments 表。


4. 驱动表和被驱动表的源码分析

        MySQL 在执行查询时,底层的表连接逻辑主要体现在 join_optimizer 中。在源码中,这一过程可以追溯到 sql/sql_select.cc 文件中的 JOIN 类,特别是 make_join_plan 函数,该函数负责生成查询计划,其中的驱动表和被驱动表的选择逻辑尤为重要。

4.1 JOIN::optimize() 函数

        JOIN::optimize() 是查询优化的主要入口,该函数负责生成查询的执行计划,包括表的顺序和连接方式。在优化过程中,它会尝试不同的连接顺序,并根据成本计算选择最优方案。

void JOIN::optimize() {...// 生成查询计划make_join_plan();...
}
4.2 make_join_plan() 函数

        make_join_plan() 函数根据优化器的成本模型选择合适的表作为驱动表和被驱动表。它会评估不同的表连接顺序,并基于查询的代价模型决定驱动表。

bool JOIN::make_join_plan() {...// 尝试不同的连接顺序best_read = best_position();...
}
4.3 best_position() 函数

        best_position() 函数会计算每个表作为驱动表的代价,选择代价最小的方案。它会考虑表的大小、过滤条件、索引使用情况等因素,最终决定驱动表和被驱动表的顺序。

bool JOIN::best_position() {for (each possible table combination) {// 计算表连接顺序的代价double cost = calculate_cost();if (cost < best_cost) {best_cost = cost;// 保存最优的连接顺序best_position = current_position;}}...
}


5. 驱动表和被驱动表的优化技巧

5.1 基于索引优化驱动表选择

        合理设计索引可以影响驱动表的选择。例如,确保在过滤条件中使用的字段上有索引,可以提高该表被选择为驱动表的可能性。

CREATE INDEX idx_salary ON employees(salary);

        在上述查询中,employees 表的 salary 字段上创建索引后,MySQL 优化器会优先选择该表作为驱动表,因为索引可以帮助更快地过滤数据。

5.2 控制表的大小

        如果可以控制表的数据量(例如通过分区、拆表等技术),可以将较小的表设为驱动表。例如,如果 departments 表非常小,而 employees 表非常大,通常应该选择 departments 作为驱动表。

5.3 合理使用 STRAIGHT_JOIN

        在某些情况下,MySQL 的优化器可能没有选择最优的驱动表。可以使用 STRAIGHT_JOIN 强制优化器按照指定的顺序执行连接,确保较小或过滤条件更严格的表作为驱动表。

SELECT * FROM departments d STRAIGHT_JOIN employees e ON d.id = e.department_id WHERE e.salary > 5000;

通过 STRAIGHT_JOIN 强制指定连接顺序,确保 departments 表作为驱动表。


6. 总结:驱动表和被驱动表的选择原则

  • 驱动表 是查询中首先扫描的表,通常选择小表或有严格过滤条件的表。
  • 被驱动表 是后续与驱动表进行关联的表,通常是较大表或者没有严格过滤条件的表。
  • MySQL 优化器根据表的大小、过滤条件、索引使用情况等因素选择驱动表,并在执行计划中做出最优选择。
  • 可以通过 EXPLAIN 命令查看执行计划,判断驱动表和被驱动表的选择情况。
  • 优化驱动表选择的方式包括:合理设计索引、控制表的数据量、使用 STRAIGHT_JOIN 强制指定连接顺序等。

理解并优化驱动表和被驱动表的选择对于提升 MySQL 查询性能具有重要意义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1558711.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

海外短剧h5/app系统开源代码(支持多语言切换/国际支付/快捷登录)+快速搭建部署指南

一、出海短剧到底还能不能做&#xff1f;从供给侧来看&#xff0c;2024年短剧出海迎来大爆发&#xff0c;众多新的短剧APP入局&#xff0c;短剧内容供给量呈现爆炸性增长&#xff0c;增速远超国内市场。 尽管海外短剧的评价毁誉参半&#xff0c;但普适性文化为其顺利出海提供了…

非刚性点云配准 Non-rigid registration of two surfaces.SHREC 14 Human 数据集

非刚性点云配准关键&#xff08;红为target&#xff0c;蓝为source&#xff09; 白色为source经过非刚性配准后的效果&#xff0c;非刚性原理上是不存在刚性变换的旋转平移矩阵的。。后面有时间填坑

RK3568平台开发系列讲解(I2C篇)i2c 总线驱动介绍

🚀返回专栏总目录 文章目录 一、i2c 总线定义二、i2c 总线注册三、i2c 设备和 i2c 驱动匹配规则沉淀、分享、成长,让自己和他人都能有所收获!😄 i2c 总线驱动由芯片厂商提供,如果我们使用 ST 官方提供的 Linux 内核, i2c 总线驱动已经保存在内核中,并且默认情况下已经…

Xshell选中内容后控制台自动输出^C,解决方案

点击钉钉左上角&#xff0c;出现如下下拉框&#xff0c;选中“设置与隐私” 选中“通用” 取消勾选 AI助理 的2个选项 系统底部任务栏显示AI助理入口 选中文本时显示AI工具栏

seL4 Notifications(六)

Notification 理解如何在任务之间设置共享内存能够使用通知对象在任务之间进行同步理解如何使用徽章进行通知区分 Background 通知允许进程发送异步信号给彼此&#xff0c;主要用于中断处理以及同步访问共享数据缓存。 信号量对象 信号是通过能力上的调用进行发送和接收到…

海洋大地测量基准与水下导航系列之二国外海底大地测量基准和海底观测网络发展现状(下)

2004年&#xff0c;英国、德国、法国等国家在欧洲“全球环境与安全监测’(Global Monitoring for Environment and Security,GMES)观测计划倡导下制定了“欧洲海底观测网络”(European Seafoor Observatory Network,ESONET)计划。ESONET是一个多学科的欧洲卓越网络(NoE &#x…

数论与同余 - 离散数学系列(七)

目录 1. 整数的性质 整除与因数 最大公约数与最小公倍数 2. 欧几里得算法 算法步骤 3. 模运算与同余 模运算 同余关系 同余的性质 4. 数论在密码学中的应用 RSA 加密算法 5. 实际应用场景 1. 数字签名 2. 哈希函数与数据完整性 3. 密钥交换 6. 例题与练习 例题…

WMS仓储管理系统与MES系统助力企业实现精细化管理

在当今这个信息化、数字化与智能化深度融合的制造业新时代&#xff0c;WMS仓储管理系统与MES管理系统的集成已成为企业提升生产效率、优化库存管理、增强市场竞争力的核心战略。这一创新性的技术整合不仅标志着制造业向更高层次智能化转型的迈进&#xff0c;更是企业实现精益生…

成都睿明智科技有限公司抖音电商服务佼佼者

在当今这个数字化浪潮汹涌的时代&#xff0c;抖音电商以其独特的魅力迅速崛起&#xff0c;成为众多商家竞相追逐的新蓝海。而在这场电商盛宴中&#xff0c;专业的服务商如同灯塔一般&#xff0c;为迷茫的商家指引方向。今天&#xff0c;我们就来深入探讨一家备受瞩目的服务商—…

docker-compose无法切换用户

问题描述 jupyter:image: flink:1.19-pyprivileged: trueuser: rootports:- "9999:8888"volumes:- /data/docker_data/jupyter:/workcommand: sh -c "cd / && jupyter notebook --ip 0.0.0.0 --port 8888 --allow-root --NotebookApp.passwordsha1:658…

从零开始学cv-17:图像绘制基本图形

文章目录 前言一、绘制直线与箭头二、绘制矩形三、绘制圆形椭圆形 前言 随着计算机视觉技术的不断发展&#xff0c;OpenCV作为一款强大的开源图像处理库&#xff0c;受到了越来越多开发者的喜爱。本文将带领读者走进OpenCV的世界&#xff0c;从基础入手&#xff0c;详细介绍如…

通过低代码平台实现CRM系统的快速开发与部署

在当今瞬息万变的商业环境中&#xff0c;企业需要快速响应市场变化&#xff0c;提升客户关系管理&#xff08;CRM&#xff09;系统的灵活性和效率。传统的CRM系统开发周期长、成本高、维护复杂&#xff0c;难以满足企业快速部署和迭代的需求。低代码平台的出现&#xff0c;为CR…

Python神仙级思维导图+入门教程(非常详细,入门从这篇开始)

入门 Python 绝非难事&#xff0c;但如何让自己坚持学下去是如今很多学习者面对的一大难题。为了避免像背单词永远停留在 abandon 一样&#xff0c;积极展开自救的小编在尝试过一些入门方法后&#xff0c;终于找到了一个超级棒的一份思维导图视频教程 这是我刚开始学习python时…

鸿蒙开发之ArkUI 界面篇 二十五 购物车

实现效果如下图&#xff1a; 为了好分析&#xff0c;我们将界面分为两部分&#xff0c;标注如下&#xff1a; 很明显区域1和区域2是垂直关系&#xff0c;用Colum容器&#xff0c;区域1又分为左右两部分&#xff0c;是水平关系&#xff0c;大容器使用的是Row&#xff0c;左边是…

爬虫实战:从HTTP请求获取数据解析社区,自动生成代码

在过去的实践中&#xff0c;我们通常通过爬取HTML网页来解析并提取所需数据&#xff0c;然而这只是一种方法。另一种更为直接的方式是通过发送HTTP请求来获取数据。考虑到大多数常见服务商的数据都是通过HTTP接口封装的&#xff0c;因此我们今天的讨论主题是如何通过调用接口来…

eBPF实战教程七 | 性能监控工具—bpftop

目录 bpftop介绍 工作原理 工具使用 功能小结 在之前的文章《USDT的预埋与性能测评》中&#xff0c;我们通过多次触发探针并统计用户态函数调用时间来分析USDT的性能&#xff0c;这种方法在编写demo时非常便捷&#xff0c;但在工程化的项目中&#xff0c;我们通常无法直接修…

竹云参编 | 《个人信息保护合规审计人员能力发展研究报告(2024)》正式发布!

近日&#xff0c;“个人信息保护合规审计实务研讨会”在北京成功举办&#xff0c;来自中国网络安全审查认证和市场监管大数据中心、中国通信学会、中国通信企业协会、中国行为法学会网络与数据法学研究部、蒙牛乳业、平安集团、大成律师事务所、竹云等80余名专家学者、行业精英…

【python实操】python小程序之魔法方法(__init__方法、__str__方法、__del__方法)

引言 python小程序之魔法方法&#xff08;__init__方法、__str__方法、__del__方法&#xff09; 文章目录 引言一、__init__方法1.1 题目1.2 代码1.3 代码解释1.3.1 逐行注释1.3.2 代码执行过程 二、__str__方法2.1 题目2.2 代码2.3 代码解释 三、__del__方法3.1 题目3.2 代码3…

2句话说通 一体化模型与矢量模型的不同

有人说:一个人从1岁活到80岁很平凡,但如果从80岁倒着活,那么一半以上的人都可能不凡。 生活没有捷径,我们踩过的坑都成为了生活的经验,这些经验越早知道࿰

安卓系统属性persist类型prop深入剖析

背景&#xff1a; 近来学员朋友在群里问道了prop属性值进行持久化存储相关的问题&#xff0c;针对prop大部分情况下都是在代码端进行get获取读取操作&#xff0c;因为很多系统属性都是ro类型的&#xff0c;即不可以修改的&#xff0c;有一些debug可以修改的属性&#xff0c;但…