带主键JOIN与无JOIN的查询性能对比:非索引WHERE条件下谁更快?
关于JOIN查询与直接单表查询的性能差异分析
首先得明确:你给出的两个查询逻辑结果可能不一样:
- JOIN版本:只返回表B中满足
where_field='some value'且在表A中有对应主键匹配的select_field - 直接查B版本:返回表B中所有满足
where_field='some value'的select_field,不管有没有表A的匹配
先把业务逻辑对齐,再谈性能:
为什么测试执行时间都是00:00:00?
这是因为你的表数据量太小,查询执行速度极快,数据库的计时精度不足以捕捉到差异。要判断性能差异,得看执行计划里的扫描行数、逻辑读/物理读次数,而不是表面的执行时间。
两种查询的性能差异拆解
1. 直接查询表B的执行逻辑
因为where_field是非索引字段,数据库会对表B做全表扫描,逐条判断where_field是否等于目标值,然后返回符合条件的select_field。全程只涉及表B的一次全扫。
2. JOIN查询的执行逻辑
由于JOIN是基于主键(主键默认是唯一索引,查找效率极高),数据库通常会有两种执行路径:
- 路径一(更优,多数情况优化器会选这个):先全表扫描表B,过滤出满足
where_field='some value'的记录,再用这些记录的pkB_field去表A的主键索引做匹配(O(1)级别的快速查找),只保留匹配成功的记录。这比直接查B多了一步主键匹配,但因为主键查找速度极快,如果过滤后的B表记录不多,额外开销几乎可以忽略。 - 路径二(较少出现,数据分布特殊时可能触发):先扫描表A的所有主键,再逐个去表B找对应的
pkB_field记录,之后过滤where_field。如果表A数据量很大,这会比直接查B慢很多——因为要做大量的主键匹配+过滤操作,远不如直接全扫B高效。
要不要避免JOIN?
不是绝对的:
- 如果业务逻辑需要只保留和表A关联的B表记录,那必须用JOIN,这时候重点是让优化器选择上述的路径一(可以通过查看执行计划确认,必要时加提示)。
- 如果业务逻辑不需要关联表A,那直接查B更简单,也少了关联的额外开销,没必要用JOIN。
内容的提问来源于stack exchange,提问作者Anthony Voronkov
相关产品推荐
相关产品推荐

