MySQL执行表关联操作时WHERE子句是否会在关联过程中生效?
SELECT * FROM A LEFT JOIN B USING (k) WHERE A.c = 'SOME VALUE'
执行逻辑问题解答
1. WHERE过滤条件的执行时机
MySQL会在两表关联前就对A表应用WHERE过滤条件,不会等两表全量关联完成后再执行过滤,原因如下:
- 该查询为左连接,A表是驱动表,
A.c = 'SOME VALUE'是针对驱动表的恒等过滤条件,这个条件下推不会改变左连接的最终查询结果,MySQL优化器会自动做条件下推优化,减少参与关联的数据量。 - 如果先全量关联再过滤,需要先扫描A表所有行和B表做关联,会产生大量无效运算,性能损耗极高,优化器在规则允许的场景下不会选择这种执行逻辑。
2. c列索引的利用方式
c是A表的索引列,该场景下的索引利用分为两种常见情况:
- 如果查询需要的A表字段都包含在c列的二级索引中:MySQL会直接通过c列索引定位所有满足
A.c = 'SOME VALUE'的条目,直接提取条目中存储的k字段值,去B表的k索引做匹配,不需要回表读取A表整行数据,即走覆盖索引优化。 - 如果存在需要回表查询的A表字段:MySQL会先通过c列索引过滤出符合条件的A表主键,再回表读取A表整行数据,之后拿行中的k值和B表的k索引做关联。部分场景还会触发索引条件下推(ICP)优化,直接在索引遍历阶段完成c值的过滤,减少回表次数。
内容的提问来源于stack exchange,提问作者Osama Maharmeh
相关产品推荐
相关产品推荐

