SQL JOIN 中索引是如何被使用的?

12次阅读

索引在sql JOIN中主要加速内表匹配,降低查找复杂度至O(log n);ON条件比WHERE更易触发右表索引;联合索引需遵循最左匹配;小表驱动哈希连接可绕过索引依赖。

SQL JOIN 中索引是如何被使用的?

索引在 SQL JOIN 中主要用来加速匹配过程,核心是减少数据库扫描行数和降低比较开销。它不直接参与连接逻辑,但显著影响执行效率,尤其在大表关联时。

索引作用在“内表”上最有效

数据库执行 JOIN 时,通常会选定一个表作为驱动表(外表),另一个作为被驱动表(内表)。索引对内表的访问提速最明显:

  • 驱动表先按条件过滤出少量行,再逐行去内表中查找匹配记录
  • 如果内表连接字段有索引,每次查找可从全表扫描(O(n))降为索引查找(O(log n))
  • 例如:users INNER JOIN orders ON users.id = orders.user_id,若 orders.user_id 有索引,性能提升显著

ON 条件比 WHERE 更容易触发右表索引

在 LEFT JOIN 或 RIGHT JOIN 中,把右表的过滤条件写在 ON 子句里,更容易让优化器使用其索引:

  • 错误写法:LEFT JOIN orders ON u.id = o.user_id WHERE o.status = 'paid' → 可能先全量连接再过滤,右表索引可能失效
  • 正确写法:LEFT JOIN orders ON u.id = o.user_id AND o.status = 'paid' → 连接阶段就限制右表范围,索引更易命中
  • EXPLAIN 查看执行计划,确认 type 是否为 refrangekey 是否显示对应索引名

联合索引要符合最左匹配原则

当连接条件涉及多个字段,或同时带排序/范围查询时,联合索引设计很关键:

  • 例如连接字段是 user_id,又常查 order_date > '2025-01-01',可建联合索引 (user_id, order_date)
  • 该索引支持单查 user_id = ?,也支持 user_id = ? AND order_date > ?
  • order_date > ? 单独用不上这个联合索引

小表驱动 + 哈希连接可绕过索引依赖

mysql 8.0+ 等支持哈希连接的场景下,索引不是唯一出路:

  • 当右表较小(如部门表、状态码表),数据库可能选择哈希连接:将小表加载进内存建哈希表,再遍历大表快速匹配
  • 此时即使大表连接字段无索引,性能仍可能优于嵌套循环 + 无索引扫描
  • 但哈希连接对内存消耗高,不适用于超大右表
text=ZqhQzanResources