MySQL LEFT JOIN 怎么优化:驱动表、索引和字段一致性

1次阅读
没有评论

LEFT JOIN 很常见,也很容易慢。它看起来只是把左表保留下来,右表匹配不到就返回 NULL,但在数据量变大后,驱动表选择、连接条件、索引和字段类型都会影响执行成本。

先理解 Nested Loop Join

MySQL 很多 join 场景可以理解为 Nested Loop Join:先从驱动表取一批数据,再拿每一行去被驱动表里查匹配记录。

如果驱动表很大,被驱动表又没有合适索引,成本会接近两张表的组合扫描。几万行乘几万行,瞬间就会变成慢查询。

所以 join 优化的第一原则是:让驱动表尽量小,让被驱动表的连接条件能走索引。

LEFT JOIN 会限制优化空间

普通 INNER JOIN 在语义允许时,优化器更容易选择小表作为驱动表。LEFT JOIN 因为要保留左表全部记录,很多时候左表会天然成为驱动表。

如果左表很大,右表很小,且业务并不需要保留左表无匹配记录,就应该考虑改成 INNER JOIN

还有一个常见规则:如果 WHERE 条件里对右表字段做了非空过滤,很多 LEFT JOIN 实际上已经等价于 INNER JOIN。这时保留 LEFT JOIN 只会让语义更混乱。

连接列必须有合适索引

被驱动表连接列应尽量有索引,复合条件也要考虑复合索引顺序。

例如:

select c.*
from hotel_info_original c
left join hotel_info_collection h
  on c.hotel_type = h.hotel_type
 and c.hotel_id = h.hotel_id
where h.hotel_id is null;

右表如果没有 (hotel_type, hotel_id) 或相关索引,每一行左表都可能触发大量扫描。

索引是否有效要看 EXPLAIN,重点关注 typekeyrowsExtra

字段类型和字符集也会影响索引

两张表连接字段看起来名字一样,不代表比较成本一样。如果字段类型、长度、字符集或排序规则不同,MySQL 可能不能高效使用索引。

字符串连接尤其要注意 collation。两边字段的字符集和排序规则不一致,可能让原本应该是 refeq_ref 的连接退化。

优化 join 时,不要只看有没有索引,还要看连接字段定义是否一致。

只选择必要字段

SELECT * 会放大 I/O、网络传输和回表成本。join 查询里应该尽量只选需要字段。

如果查询只需要索引里的字段,可以利用覆盖索引减少回表。如果需要大字段,考虑延迟查询或拆分查询,避免在 join 阶段带着大字段到处跑。

实用结论

优化 LEFT JOIN 先看语义,再看执行计划。

能用 INNER JOIN 就不要硬用 LEFT JOIN;必须保留左表时,尽量过滤左表、给右表连接列建合适索引,并确保连接字段类型和字符集一致。最终不要凭感觉判断,EXPLAIN 才是第一证据。

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-07-05发表,共计1127字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)