inner join只返回两张表中都匹配的行,用于必须满足双方都有数据的场景,如查既有订单又有用户信息的记录;关联字段需类型一致、有索引且非空;性能差多因缺失索引或on条件过松。

INNER JOIN 只返回两张表中都匹配的行,没有匹配的记录会被直接丢弃——这是它和 LEFT JOIN 最本质的区别,别用错场景。
什么时候必须用 INNER JOIN
当你明确只需要「双方都有数据」的结果时才用。比如查「既有订单又有用户信息的记录」,或「商品表里有库存且已上架的商品详情」。
- 用户表
users和订单表orders关联,但只想看下过单的用户(排除注册未下单的) - 课程表
courses和教师表teachers关联,只取已分配任课教师的课程 - 误用 LEFT JOIN 写成 INNER JOIN 后发现结果变少,大概率是某张表里存在空关联字段(如
orders.user_id为 NULL)
ON 子句里写什么才安全
必须用两张表中「逻辑上等价、类型一致、且有索引支持」的字段做关联。常见错误是拿字符串和数字硬比,或忽略 NULL 处理。
- 正确:
ON users.id = orders.user_id(两边都是整型主键/外键) - 危险:
ON users.email = orders.customer_email——若 email 有大小写混存、前后空格或 NULL,匹配会失败 - 更危险:
ON CAST(orders.amount AS INT) = prices.price_id——类型强转可能报错,且无法走索引 - 如果关联字段可能为 NULL,
INNER JOIN本身就会跳过这些行,不用额外加WHERE xxx IS NOT NULL,但得确认这是否符合业务预期
性能差?先看执行计划里的“Rows Examined”
INNER JOIN 慢,90% 是因为没在 ON 字段建索引,或者写了多个 JOIN 导致笛卡尔积放大。
- 检查
EXPLAIN SELECT ... INNER JOIN ...输出中key列是否用了索引;若显示NULL,说明没走索引 - 两张表关联后结果集比任一原表还大?可能是 ON 条件太松(比如用城市名代替城市 ID 关联)
- 三张表连 JOIN 时,数据库优化器可能选错驱动表顺序。可尝试用
STRAIGHT_JOIN(MySQL)或重写子查询控制顺序 - 避免在 ON 里写函数,例如
ON DATE(orders.created_at) = '2024-01-01'——会导致索引失效
最常被忽略的一点:INNER JOIN 的结果默认不保证顺序,哪怕两张表各自有序。真要按某字段排序,ORDER BY 必须显式写,不能依赖 JOIN 顺序或源表主键排列。










