MySQL优化实战:当LEFT JOIN不按套路出牌时,如何强制指定驱动表?

【MySQL】驱动表、被驱动表详解。—— 性能优化。 阅读详情

MySQL优化实战:当LEFT JOIN不按套路出牌时,如何强制指定驱动表?

在数据库性能调优的战场上,LEFT JOIN 常常被我们视为一种“确定性”的操作。很多开发者,甚至一些经验丰富的DBA,都默认一个信条:写在 LEFT JOIN 左边的表,就是查询的驱动表。这个认知在大多数简单场景下是成立的,它符合我们的直觉,也简化了初学者的理解。然而,当你面对的是千万级甚至亿级数据表关联的复杂查询时,这种“想当然”的认知可能会成为性能瓶颈的隐形推手,甚至导致执行计划与你的预期背道而驰,让查询响应时间从毫秒级骤降至分钟级。

MySQL的查询优化器是一个极其复杂的“黑盒”,它的核心目标是以最低的预估成本完成查询。这个“成本”的计算,综合了表的大小、索引情况、过滤条件、统计信息等多种因素。当优化器认为,将 LEFT JOIN 右边的表作为驱动表,并使用 INNER JOIN 的算法来执行,其成本远低于按照 LEFT JOIN 字面顺序执行时,它就会毫不犹豫地“改写”你的查询逻辑。这时,你看到的 EXPLAIN 输出可能会让你大吃一惊:驱动表竟然不是左边那个!

这种优化器“自作主张”的行为,在多数情况下是良性的,旨在提升效率。但在某些特定场景下,它却可能是灾难性的。例如,当你明确知道左表经过精心筛选后结果集极小,而右表虽然巨大但拥有高效索引时,你期望左表驱动右表,走高效的 Index Nested-Loop Join。但优化器可能因为右表某个字段的 WHERE 条件,误判了语义,将查询改写为 INNER JOIN 并选择了右表作为驱动表,从而触发全表扫描,性能一落千丈。

本文正是为那些已经跨越基础SQL编写、开始深入性能腹地的高级开发者和DBA所准备。我们将不再停留在“小表驱动大表”的原则性讨论上,而是直接切入实战,深入剖析 LEFT JOIN 执行计划“失控”的背后原理,并重点传授如何像一位经验丰富的指挥官一样,从优化器手中夺回对 JOIN 顺序的绝对控制权。我们将探讨 STRAIGHT_JOIN 这一“尚方宝剑”的利与弊,并揭示其他间接影响驱动表选择的高级技巧,让你在面对复杂关联查询时,能够精准施策,确保执行计划始终行驶在最优路径上。

1. 理解驱动表:LEFT JOIN 的“潜规则”与优化器的“背叛”

要掌控 JOIN,首先必须透彻理解驱动表(Driving Table)与被驱动表(Driven Table)在查询执行过程中的角色与工作流。这不仅仅是两个名词,而是理解整个 JOIN 性能的基石。

1.1 驱动表与被驱动表的工作机制

你可以把一次 JOIN 查询想象成一场嵌套循环。驱动表就是外层循环的源头。MySQL会首先读取驱动表的数据(可能经过 WHERE 条件过滤),得到一份结果集。然后,对于这份结果集中的每一行,数据库引擎都会去被驱动表中寻找能够匹配的行。这个“寻找”的过程,就是内层循环。

-- 一个概念上的伪代码展示JOIN过程
for each row_D in driving_table { // 遍历驱动表的每一行
    for each row_P in driven_table { // 针对驱动表的当前行,遍历被驱动表
        if (join_condition_is_true(row_D, row_P)) {
            output_row(row_D, row_P); // 输出匹配的行
        }
    }
}

从这个模型可以清晰地看出一个黄金法则:驱动表的结果集越小,外层循环的次数就越少,整个 JOIN 操作的总体成本往往就越低。这就是“小表驱动大表”这一经典优化原则的根源。这里的“小表”并非绝对的数据量小,而是指参与本次 JOIN 时,经过所有可用条件过滤后,剩余的结果集小。

1.2 为什么LEFT JOIN的左边不一定是驱动表?

LEFT JOIN 的语义是:返回左表的所有行,即使右表中没有匹配的行。在SQL的书写逻辑上,左表占据主导地位。然而,MySQL优化器在生成物理执行计划时,其首要目标不是维持书写顺序,而是最小化查询的执行成本。

优化器会对你的SQL语句进行重写和变换,其中一种关键的变换就是“外连接化简”。当优化器发现,WHERE 子句中的某个条件隐式地将 LEFT JOIN 转换成了 INNER JOIN 的语义时,它就会大胆地进行改写。

让我们看一个经典的“背叛”案例:

假设我们有两个表:orders(订单表,数据量小但频繁更新)和 order_details(订单详情表,数据量巨大但带有 order_id 索引)。

-- 查询1:标准的LEFT JOIN,意图列出所有订单,及其详情(如果有的话)
SELECT *
FROM orders o
LEFT JOIN order_details od ON o.id = od.order_id;

在这个查询中,orders 表大概率是驱动表,因为它通常更小,且 LEFT JOIN 语义明确。

现在,我们添加一个针对右表 order_details 的 WHERE 条件:

-- 查询2:在WHERE中过滤右表字段
SELECT *
FROM orders o
LEFT JOIN order_details od ON o.id = od.order_id
WHERE od.quantity > 10; -- 对右表字段进行过滤

关键点来了:WHERE od.quantity > 10 这个条件,会过滤掉所有 order_details 中不满足条件的行,同时也过滤掉了那些因为 LEFT JOIN 而未匹配成功、od.* 字段全部为 NULL 的行。因为 NULL > 10 的结果是 NULL(即假)。最终结果集里,不会出现任何右表为 NULL 的行。这意味着,这个查询的实际效果和一个 INNER JOIN 加上 od.quantity > 10 条件是完全一样的。

优化器洞察到了这一点。它会在内部将查询重写为:

-- 优化器可能的重写结果
SELECT *
FROM orders o
INNER JOIN order_details od ON o.id = od.order_id
WHERE od.quantity > 10;

一旦被重写为 INNER JOIN,优化器就不再受 LEFT JOIN 书写顺序的约束。它会重新评估 orders 和 order_details 的成本:谁做驱动表扫描的行数更少、利用索引的效率更高。如果 order_details 表在 quantity 和 order_id 上有合适的复合索引,优化器极有可能选择 order_details 作为驱动表,因为它可以先利用 quantity > 10 这个条件快速筛选出一小部分数据,再用索引去关联 orders 表。这时,EXPLAIN 结果就会显示驱动表是 order_details。

注意:你可以通过 EXPLAIN EXTENDED 后执行 SHOW WARNINGS; 来查看优化器重写后的查询语句,这是洞察优化器思维的宝贵工具。

2. 夺回控制权:使用STRAIGHT_JOIN强制驱动表顺序

当你经过分析,确信自己的 JOIN 顺序才是最优解,而优化器的选择是错误的时候,你就需要一种强制手段。STRAIGHT_JOIN 正是为此而生。它在功能上完全等同于 INNER JOIN,但有一个至关重要的附加指令:强制按照 FROM 子句中表的书写顺序来确定驱动表。

2.1 STRAIGHT_JOIN的语法与语义

它的使用非常简单,直接用 STRAIGHT_JOIN 关键字替换你的 JOIN 关键字(通常是 INNER JOIN 或隐含的 JOIN),并确保表顺序符合你的预期。

-- 优化器可能选择b表或a表作为驱动表
SELECT *
FROM table_a a
JOIN table_b b ON a.key = b.key
WHERE a.some_col = 'value' AND b.other_col > 100;

-- 使用STRAIGHT_JOIN,强制a表作为驱动表
SELECT *
FROM table_a a
STRAIGHT_JOIN table_b b ON a.key = b.key
WHERE a.some_col = 'value' AND b.other_col > 100;

对于 LEFT JOIN,你需要先将查询语义梳理清楚。如果优化器因为 WHERE 条件将你的 LEFT JOIN 误判并重写,而你仍需要 LEFT JOIN 的语义,首先要做的是修正查询,将右表过滤条件移到 ON 子句中。

-- 问题查询:LEFT JOIN语义被WHERE破坏,优化器可能重写并选择错误驱动表
SELECT *
FROM orders o
LEFT JOIN order_details od ON o.id = od.order_id
WHERE od.quantity > 10;

-- 修正1:恢复LEFT JOIN语义,但优化器仍可能选择驱动表
SELECT *
FROM orders o
LEFT JOIN order_details od ON o.id = od.order_id AND od.quantity > 10;

-- 修正2:在恢复语义的基础上,使用STRAIGHT_JOIN强制驱动表顺序
-- 注意:STRAIGHT_JOIN本身是INNER JOIN,所以这里不能直接替换LEFT JOIN。
-- 正确做法是,如果你确定要强制顺序且语义就是INNER JOIN,才用STRAIGHT_JOIN。
-- 如果必须是LEFT JOIN语义,STRAIGHT_JOIN不适用。此时应依赖其他手段(见第3章)。
SELECT *
FROM orders o
STRAIGHT_JOIN order_details od ON o.id = od.order_id
WHERE od.quantity > 10; -- 此时语义已等同于INNER JOIN

核心要点:STRAIGHT_JOIN 只适用于 INNER JOIN 语义的场景。如果你需要的是真正的 LEFT JOIN(即左表所有行都必须返回),那么 STRAIGHT_JOIN 无法直接使用。在这种情况下,优化器如果选择了错误的驱动表,往往是因为查询本身写法导致了语义变化。你的首要任务是修正查询,恢复正确的 LEFT JOIN 语义。

2.2 STRAIGHT_JOIN的双刃剑:何时该用,何时慎用

STRAIGHT_JOIN 是一把威力巨大但也非常危险的手术刀。它绕过了优化器的成本计算,将执行计划的选择权完全交给了开发者。

应当考虑使用 STRAIGHT_JOIN 的场景:

  1. 你比优化器更懂数据:你明确知道某个表经过特定条件过滤后,结果集极小(例如,根据主键或唯一索引查询单条记录),而优化器因为统计信息过时或成本模型偏差,错误地选择了大表作为驱动表。
  2. 关联顺序依赖业务逻辑:在多表(超过2个)复杂关联时,关联顺序可能影响中间结果集的大小。你通过手动分析,找到了一条最优的关联路径,而优化器没有选中这条路径。
  3. 调试与对比:作为性能调优的调试手段,通过强制顺序与优化器选择顺序进行对比测试,直观验证哪种顺序效率更高。

必须谨慎或避免使用 STRAIGHT_JOIN 的场景:

  1. 数据分布动态变化:如果你强制了顺序,但未来驱动表的数据量增长远快于被驱动表,今天的优化可能成为明天的灾难。STRAIGHT_JOIN 写死的顺序缺乏弹性。
  2. 统计信息更新后:当你对表进行了 ANALYZE TABLE 更新了统计信息,优化器可能会做出更优的选择。而 STRAIGHT_JOIN 会阻止优化器利用新的信息。
  3. 索引结构发生变化:新增或删除了关键索引,会彻底改变 JOIN 的成本计算。被 STRAIGHT_JOIN 锁定的计划可能不再高效。
  4. 你不完全确定时:如果你对数据分布、索引选择、JOIN 算法没有十足把握,那么信任优化器通常是更安全的选择。优化器在绝大多数常规场景下的表现是可靠的。

提示:在使用 STRAIGHT_JOIN 之前,务必先使用 EXPLAIN 对比强制前后两种执行计划的差异,并在测试环境用真实数据量进行性能基准测试。不要在生产环境盲目使用。

3. 高级引导术:不依赖STRAIGHT_JOIN的影响驱动表策略

除了 STRAIGHT_JOIN 这种“强制命令”,还有一些更优雅、更灵活的技巧,可以“引导”优化器做出你期望的选择。这些方法更像是与优化器进行“协商”,而非“命令”。

3.1 利用子查询或派生表固定结果集

优化器在决定驱动表时,会评估每个表(或子查询结果)的“大小”。你可以通过子查询,提前将一个复杂的过滤操作固定下来,并让优化器将这个子查询的结果集视为一个独立的、已知大小的“表”。由于子查询的结果集通常较小且确定,优化器更倾向于将其作为驱动表。

-- 假设我们想以“今日活跃用户”这个小结果集来驱动大表`user_activities`
-- 原始查询,优化器可能选择大表`user_activities`作为驱动表
SELECT u.id, u.name, COUNT(ua.id)
FROM users u
LEFT JOIN user_activities ua ON u.id = ua.user_id AND ua.date = CURDATE()
WHERE u.status = 'active'
GROUP BY u.id;

-- 使用子查询引导:先将“今日活跃用户”这个结果集固定下来
SELECT active_users.id, active_users.name, COUNT(ua.id)
FROM (
    SELECT id, name -- 子查询产生一个小结果集
    FROM users
    WHERE status = 'active'
) AS active_users
LEFT JOIN user_activities ua ON active_users.id = ua.user_id AND ua.date = CURDATE()
GROUP BY active_users.id;

在这个改写中,子查询 active_users 明确地先过滤出了状态为活跃的用户。优化器在评估时,会认为 active_users 这个派生表的数据量很小,从而大概率将其选为驱动表去关联 user_activities。

3.2 索引的“诱惑”与WHERE条件的“权重”

优化器对索引有着天然的偏好。如果一个表拥有完美的索引可以覆盖 WHERE 条件和 JOIN 条件,那么它被选为驱动表的几率会大大增加。

  • 为驱动表候选列创建高效索引:如果你希望A表驱动B表,确保A表上用于过滤(WHERE)和连接(ON)的列上有合适的索引。这能显著降低优化器估算的A表扫描成本。
  • 调整WHERE条件的 selectivity:优化器会根据 WHERE 条件估算出每个表最终的结果集大小。你可以通过添加更具选择性的条件(例如,通过一个范围很小的时间字段 create_time > ‘2024-01-01’),来“暗示”优化器这个表的结果集很小,适合做驱动表。反之,如果一个表没有 WHERE 条件过滤,它可能就会被认为需要全表扫描,从而不适合做驱动表。

3.3 调整JOIN顺序的书写习惯

虽然对于 INNER JOIN,优化器理论上可以任意调整表的顺序,但有些优化器实现(或在某些简单情况下)可能会在一定程度上参考书写顺序。对于 LEFT JOIN 和 RIGHT JOIN,外层表的顺序是固定的,但你可以通过嵌套 JOIN 或改变查询结构来间接影响内层 JOIN 的顺序。

-- 多表JOIN时,不同的书写顺序有时会暗示不同的优化思路
SELECT *
FROM large_table l
JOIN medium_table m ON l.id = m.l_id
JOIN small_table s ON m.id = s.m_id
WHERE l.category = 'A';

-- 与上面的查询逻辑相同,但书写顺序强调了从小表开始关联的思路
SELECT *
FROM small_table s
JOIN medium_table m ON s.m_id = m.id
JOIN large_table l ON m.l_id = l.id
WHERE l.category = 'A';

第二种写法在逻辑上更清晰地表达了“由小到大”的关联意图,虽然优化器最终可能仍会自行决定,但这种清晰的逻辑有时能帮助优化器(以及未来的代码维护者)更好地理解查询意图。

4. 实战诊断与决策流程:从EXPLAIN到最优JOIN

理论知识需要落地到实战。下面我们构建一个完整的决策流程,当你面对一个性能不佳的 JOIN 查询时,可以按图索骥,找到问题根源并实施优化。

4.1 诊断四步法

第一步:获取并解读EXPLAIN 这是所有性能调优的起点。不要只看 EXPLAIN 的第一行(驱动表),要关注整个执行计划树。

  • type 列:关注是否是 ALL(全表扫描),应努力使其达到 ref、eq_ref、range 或 index。
  • key 列:实际使用的索引。
  • rows 列:优化器预估需要扫描的行数,是判断“大小表”的关键。
  • Extra 列:注意 Using where; Using join buffer (Block Nested Loop) 这样的信息,它可能暗示了低效的 JOIN 算法。

第二步:分析驱动表选择是否合理 根据 EXPLAIN 的 rows 预估,判断当前选择的驱动表是否真的是“小结果集”。同时,检查查询语句:

  • 是否存在将 LEFT JOIN 变为 INNER JOIN 语义的 WHERE 条件?(右表字段的 IS NOT NULL 或等值判断)
  • 驱动表上的 WHERE 条件是否有合适的索引?
  • 被驱动表上的 JOIN 条件是否有索引?

第三步:进行对比实验 如果怀疑驱动表选择不当,不要急于使用 STRAIGHT_JOIN。

  1. 先尝试优化索引:为候选驱动表的过滤条件加索引,为被驱动表的连接条件加索引。
  2. 尝试使用子查询重写,固定小结果集。
  3. 最后,再考虑使用 STRAIGHT_JOIN 强制顺序,并与原执行计划进行性能对比测试。

第四步:监控与迭代 优化不是一劳永逸的。在应用了优化手段后,需要在生产环境监控该查询的执行时间变化。定期(例如,每周或数据量增长10%后)重新审视 EXPLAIN 计划,确保其依然高效。

4.2 不同场景下的策略选择表

为了更直观地展示在不同情况下该如何选择优化策略,我整理了以下决策参考表:

场景特征可能的问题推荐优化策略风险与注意
LEFT JOIN 右表字段出现在 WHERE 中语义被改写为 INNER JOIN,驱动表顺序失控1. 将右表过滤条件移至 ON 子句。
2. 若仍需 WHERE 过滤,确认语义是否正确。
确保业务逻辑允许改变过滤时机。
多表关联(>3),中间结果集膨胀优化器选择的关联顺序导致中间临时表巨大1. 使用子查询预先过滤核心表。
2. 分析数据关系,手动设计关联路径,可考虑 STRAIGHT_JOIN。
手动设计需充分理解数据关系和体量,STRAIGHT_JOIN 需严格测试。
统计信息不准(如新表大量导入后)优化器基于错误信息选择了低效计划1. 执行 ANALYZE TABLE 更新统计信息。
2. 若问题依旧,再考虑使用提示或重写。
优先更新统计信息,这是最安全、首选的步骤。
驱动表缺乏高效过滤索引驱动表扫描行数过多首要任务:为驱动表的 WHERE 条件创建索引。索引是性价比最高的优化手段,应优先于调整 JOIN 顺序。
被驱动表缺乏连接条件索引导致 Block Nested-Loop Join,性能极差强制任务:为被驱动表的 JOIN 字段创建索引。没有索引,无论谁驱动谁,性能都可能很差。

4.3 一个完整的调优案例

假设我们有一个电商查询,找出过去24小时内下过订单且订单金额大于100元的所有用户及其最新订单信息。表结构简化如下:

  • users (主键 id, 索引 created_at)
  • orders (主键 id, 外键 user_id, 索引 user_id, created_at, amount)

初始低效查询:

SELECT u.*, o.order_no, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)
AND o.amount > 100
ORDER BY u.id;

问题诊断:WHERE 条件 o.created_at > ... AND o.amount > 100 作用于右表 orders,破坏了 LEFT JOIN 语义,查询被重写为 INNER JOIN。优化器可能选择 orders 作为驱动表,利用 created_at 和 amount 的索引先筛选订单,再去关联 users。但如果近期大额订单很少,而 users 表巨大,这个计划可能不是最优。

优化步骤:

  1. 修正语义:如果业务确实需要 LEFT JOIN(列出所有用户,仅显示其符合条件的大额订单),则条件应移至 ON 子句。
    SELECT u.*, o.order_no, o.amount
    FROM users u
    LEFT JOIN orders o ON u.id = o.user_id 
                        AND o.created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)
                        AND o.amount > 100
    ORDER BY u.id;
    
    此时,users 是明确的驱动表。
  2. 如果语义本就是INNER JOIN:我们就是想要“有近期大额订单的用户”。
    SELECT u.*, o.order_no, o.amount
    FROM users u
    JOIN orders o ON u.id = o.user_id
    WHERE o.created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)
    AND o.amount > 100
    ORDER BY u.id;
    
  3. 分析数据:假设我们知道 users 表有1000万行,而过去24小时金额大于100的订单只有1万行。那么,用 orders 驱动 users 显然是更优的(1万次索引查找 vs 可能1000万次扫描)。优化器很可能自动做出正确选择。如果它没有,我们可以引导。
  4. 引导优化器:使用子查询强调小结果集。
    SELECT u.*, sub.order_no, sub.amount
    FROM (
        SELECT user_id, order_no, amount
        FROM orders
        WHERE created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)
        AND amount > 100
    ) AS sub -- 先筛选出1万行的小结果集
    JOIN users u ON sub.user_id = u.id
    ORDER BY u.id;
    
  5. 最终手段:如果经过 EXPLAIN 对比和测试,发现优化器在步骤4中仍然选择了低效计划(虽然概率很低),并且你极度确信自己的顺序最优,最后才考虑:
    SELECT u.*, o.order_no, o.amount
    FROM orders o STRAIGHT_JOIN users u ON o.user_id = u.id
    WHERE o.created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)
    AND o.amount > 100
    ORDER BY u.id;
    

在我处理过的许多性能案例中,驱动表选择错误往往只是表面现象,深层次的原因通常是索引缺失、查询语义被意外改写,或者统计信息陈旧。盲目使用 STRAIGHT_JOIN 就像给一个发烧的病人直接使用退烧药,可能暂时压下症状,却忽略了体内的感染。真正的高手,会从 EXPLAIN 这个“体检报告”入手,结合业务逻辑和数据特征,先尝试通过调整查询写法、创建合适索引这些“治本”的方法来解决问题。STRAIGHT_JOIN 应该是工具箱里最后一件、也是最需要敬畏的一件工具,它代表着你完全接管了优化器的工作,也承担了随之而来的所有责任。

架构设计之架构治理 架构治理的本质是“用规则约束复杂性,用流程保障落地,用数据驱动优化”先定目标:明确量化的治理目标,避免盲目行动;立标准:建立覆盖分层、选型、接口、拆分的统一规范,奠定治理基础;强评审:通过架构评审把控设计环节,提前规避风险;全流程:将治理规则贯穿设计、开发、测试、部署、运维全生命周期;重保障:通过组织、流程、工具确保治理落地,而非“纸上谈兵”;持续迭代:随业务与技术演进优化治理规则,避免“一劳永逸”。 阅读详情

相关推荐

LVGL字体优化实战:如何将中文字库放到外部SPI Flash并动态加载(节省内部RAM)

本文详细介绍了LVGL在嵌入式UI开发中如何通过外部SPI Flash存储中文字库并动态加载,以节省内部RAM资源。通过对比不同存储介质和字库格式,提供多种实现方案及性能优化技巧,帮助开发者在资源受限设备上实现高效的中文显示。

weixin_28693683的博客 341

mysql驱动表与被驱动表及join优化

MySQL 表关联的算法是 Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据。忘了补充一句,也可以通过EXPLAIN分析来判断在sql中谁是驱动表,EXPLAIN语句分析出来的第一行的表即是驱动表。3.当使用join时,mysql会选择数据量比较小的表作为驱动表,大表作为被驱动表。如果A表,B表数据量差不多大的时候,那么选择谁作为驱动表也是无所谓了。1.当使用left join时,左表是驱动表,右表是被驱动表。

牧竹子 2469

Kali下RTL8812AU网卡5G抓包精准适配指南

WiFi监听模式是无线安全测试的基础能力,其核心在于网卡驱动对802.11a/n/ac协议栈的完整支持。RTL8812AU系列USB无线网卡因成本低、兼容性广被广泛用于渗透测试,但其芯片版本碎片化(如VA/VC/ACM)与Linux内核演进(6.1~6.5)存在严重适配断层,导致5GHz频段Beacon帧捕获失败、信道切换异常、注入功能残缺等典型问题。技术价值在于突破‘即插即用’幻觉,建立从USB设备ID识别、固件版本校验到射频寄存器级补丁的全链路可控流程。典型应用场景包括CTF无线赛题实战、红蓝对抗中的W

weixin_33783283的博客 760

mysql 指定驱动表_了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

一、为什么要用小表驱动大表 1、驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表](Important!) 忠告:如果你搞不清楚该让谁做驱动表、谁 join 谁,请让 MySQL 运行时自行判断 既然“未指定联接条件时,行数少的表为[驱动表]”了,而且你也对自己写出的复...

weixin_28943045的博客 538

[图解]SysML与EA实战:住宅安全系统接口块设计全解析

本文详细解析了使用SysML和EA工具进行住宅安全系统接口块设计的全流程。从系统上下文图入门到接口块实战技巧,涵盖块定义图与内部块图的视角转换,以及多图协同建模方法论。特别分享EA工具的高效操作指南和常见问题避坑建议,帮助工程师掌握精确信号定义、端口方向设置等关键技能,提升安防系统设计效率。

weixin_29234509的博客 331

碳化硅外延层厚度测量:红外干涉光谱与FFT技术详解

薄膜厚度测量是半导体制造中的关键工艺控制环节,其核心原理基于光的干涉现象。当光在薄膜上下界面反射并叠加时,会产生与厚度相关的干涉条纹。通过分析这些条纹,可以非接触、无损地获取薄膜的精确厚度信息。这项技术的核心价值在于实现了对关键工艺参数的在线、快速监控,对于提升器件性能与生产良率至关重要。在第三代半导体,尤其是碳化硅功率器件的制造中,外延层厚度直接决定了器件的击穿电压和导通电阻等核心性能。红外干涉光谱法因其对碳化硅材料在红外波段的良好透过性,成为该领域主流的厚度测量方案。通过快速傅里叶变换(FFT)对采集到

weixin_29032489的博客 306

【性能提升神器】STRAIGHT_JOIN

今天给大家下另一个性能提升神器-STRAIGHT_JOIN,在数据量大的联表查询中灵活运用的话,能大大缩短查询时间。 首先来解释下STRAIGHT_JOIN到底是用做什么的: STRAIGHT_JOIN is similar to JOIN, except that the left table is always read before the right table. This can b...

weixin_33739627的博客 331

CAN 通信测试工具 canutils

概述 CAN,Controller Area Network,控制器局域网,一种高可靠性的现场总线。广泛用于汽车电子、工业控制通信。 canutils 工具包内含 5 个独立的程序:canconfig、candump、canecho、cansend、cansequence。这几个程序的功能简述如下: canconfig:用于配置 CAN 总线接口的参数,主要是波特率和模式。 candump...

一个软件工程师的技术笔记 1万+

MySQL的驱动表和被驱动表

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

goTsHgo的博客 1521

搞定ESD(五):静电放电问题分析与调试

前面深入分析了静电放电的干扰机理、耦合路径,从现在开始将进入下一个大家非常关注的环节:静电放电问题分析与调试,掌握静电放电问题的分析方法,快速锁定敏感设备或者耦合路径,可以达到事半功倍的效果。

记得诚 2793

芒果YOLOv5改进107:ARConv自适应旋转卷积,全网首发 | 即插即用:以增强其表征能力,从而准确检测方向物体,ICCV顶会论文idea

ARConv自适应旋转卷积,全网首发 | 即插即用:以增强其表征能力,从而准确检测方向物体,ICCV顶会论文idea

包括YOLOv5、YOLOv7、YOLOv8等模型改进 955

MySQL --- 多表查询 & 驱动表

指从多张表中查询数据,就是从多张表当中进行查询单表查询的SQL语句:select 字段列表 from 表名;那么要执行多表查询,只需要使用逗号分隔多张表即可,如: select 字段列表 from 表1, 表2;-- 多表查询:直接在from之后跟上多张表就可以了,多张表之间使用逗号分隔可以看到,在多表查询的结果当中,每个员工都展示了5次,将每个员工分别和五个部门进行了一次匹配, 也就是将17个员工和5个部门挨个组合了一次,就是17 * 5 = 85。

weixin_53622554的博客 1万+

2、系统建模、状态估计与故障诊断中的滤波设计与故障诊断方法

本文综述了系统建模、状态估计与故障诊断中的滤波设计与故障诊断方法。首先介绍了基于分析模型、知识和信号处理的三类故障诊断方法及其特点;随后总结了传统滤波方法(如维纳滤波、卡尔曼滤波)与非概率的集员滤波方法,重点阐述了在未知但有界噪声假设下的椭球、立方、多面体、区间和Zonotope等集员滤波算法原理与发展。文章还展示了各类集员滤波算法的应用实例与流程图,并对比了其计算复杂性与准确性。最后指出,根据不同系统特性选择合适的故障诊断与滤波方法至关重要,未来趋势将趋向于多方法融合与实际工程应用深化。

kmeans3miner的博客 137

MySQL---join驱动表的选择

文章目录join关键字IndexNested-Loop JoinBlock Nested-Loop Join小表的概念总结: join关键字 当业务需要从多个数据表中读取数据时,可以使用SQL语句中的连接(JOIN),在两个或多个数据表中查询数据。 JOIN 按照功能可分为三类: INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录; LEFT JOIN(左连接):获取左表中的所有记录,即使在右表没有对应匹配的记录; RIGHT JOIN(右连接):与 LEFT JOIN 相反,用于

MAKEJAVAMAN的博客 3191

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

MySQL实战45讲学习笔记----join原理与优化

join语句执行原理 NLJ,SNL,BNL,BKA算法 创建两个表t1和t2,存储过程idata()往表t2里插入了1000行数据,在表t1里插入的是100行数据。 CREATE TABLE `t2` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, PRIMARY K...

大魔王 1101

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

MySQL驱动表

文章目录驱动表定义mysql关联查询的概念驱动表与被驱动表总结三级目录 驱动表定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表](重要) 忠告:如果你搞不清楚该让谁做驱动表、谁 join 谁,请让 MySQL 运行时自行判断 既然“未指定联接条件时,行数少的表为[驱动表]”了,而且你也对自己写出的复杂的 Nested Loop Join 不太有把握(如下面的实例所示),就别指定谁 left/rig

qq_32078397的博客 3148

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

mysql 指定驱动表_mysql驱动表STRAIGHT_JOIN

问题通过「SHOW FULL PROCESSLIST」语句很容易就能查到问题SQL,如下:SELECT post.*FROMpostINNER JOIN post_tag ON post.id =post_tag.post_idWHERE post.status = 1 AND post_tag.tag_id = 123ORDER BY post.created DESCLIMIT100说明:因为...

weixin_33277215的博客 1254

mysql join表驱动表的选择

当mysql join时,会根据一些规则选择驱动表。 https://blog.youkuaiyun.com/qq_27529917/article/details/87904179

fusugongzi的博客 1001

inner join 和 exists 效率_掌握 MySQL 这 19 个骚操作,效率至少提高3倍

1、EXPLAIN做MySQL优化,我们要善用EXPLAIN查看SQL执行计划。下面来个简单的示例,标注(1、2、3、4、5)我们要重点关注的数据:type列,连接类型。一个好的SQL语句至少要达到range级别。杜绝出现all级别。key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式。key_len列,索引长度。rows列,扫描行数。该值是个预估值。extra列,详细说...

weixin_39686192的博客 832

【explain】MySQL联表查询中的驱动表

写在前面 1、不要求每个人一定理解 联表查询(join/left join/inner join等)时的mysql运算过程 2、不要求每个人一定知道线上(现在或未来)哪张表数据量大,哪张表数据量小 3、但把mysql客户端(如SQLyog,如HeidiSQL)放在桌面上,时不时拿出来 explain 一把,这是一种美德! 在实例讲解之前,我们先回顾一下联表查询的基础知识

谭倩倩 9101

mysql 强制使用索引 FORCE INDEX(idx_name)

mysql 在查询时 如果查询语句中犹豫某些原因未使用到索引,导致查询很慢,可以强制使用索引。 如 EXPLAIN SELECT cr.id FROM car_record cr LEFT JOIN camera c ON cr.camera_id=c.id LEFT JOIN pile p ON p.pile_id=c.pile_id LEFT JOIN station s ON c.station_id=s.station_id LEFT JOIN county co ON s.count

M_azed的博客 6715

什么是MySQL JOIN查询的驱动表和被驱动表?

驱动表是 MySQL 优化器选择的优先查询的表。查询先从驱动表中检索数据,再根据驱动表的结果与被驱动表进行关联。驱动表通常记录较少、匹配数据更精准,或能利用索引高效查找的数据表。

程序新视界 1095

项目中常用的19条MySQL优化

作者:zhangqh来源:http://segmentfault.com/a/1190000012155267一、EXPLAIN做MySQL优化,我们要善用 EXPLAIN 查看SQL执...

JAVA高级架构 431

数据库连表查询如何确定驱动表

驱动表]的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表]; 2)未指定联接条件时,行数少的表为[驱动表](Important!)。 left join 则左边的为驱动表 right join 则右边的为驱动表 EXPLAIN 结果中,第一行出现的表就是驱动表(Important!) 对驱动表可以直接排序,对非驱动表(的字段排序)

一个码农的博客 3080

对驱动表和被驱动表的深入理解

不论对于nest loop 还是hash join的方式,决定驱动表和被驱动表,需要综合表的数据量大小和表数据的适合访问方式(随机读取或顺序读取)来确定。 对于循环嵌套 nest loop的表联结方式 驱动表,即需要从驱动表中拿出来每条记录,去与被驱动表的所有记录进行匹配探测。 理解驱动表和被驱动表的差异,最本质的问题,需要理解顺序读取和随机读取的差异,内存是适合随机读取...

liuyouzhang89的专栏 1万+

连表查询之驱动表

联表查询注意谁是驱动表&你搞不清楚谁join谁更好时请放手让mysql自行判定   写在前面的话:    不要求每个人一定理解 联表查询(join/left join/inner join等)时的mysql运算过程;    不要求每个人一定知道线上(现在或未来)哪张表数据量大,哪张表数据量小;     但把mysql客户端(如SQLyog,如HeidiSQL)放在桌面上,时不时拿出来

写给自己看 5252
上一篇: EPLAN电气设计进阶-结构标识符实战技巧与避坑指南
下一篇: ollama+open_webui在Ubuntu22.04上的性能优化指南:从基础安装到GPU加速配置
python9snake
博客等级 码龄1天 0粉丝 1724原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值