外层查询添加过滤条件的性能影响及SQL优化相关疑问
MySQL嵌套查询与性能优化疑问解答
原始查询语句
select * from ( select * from JOINS ON A LOT OF TABLES) as t1 where t1.col1="A" and t1.col2="B" limit 100;
1. 该语句是否会先获取内层查询的所有行,再执行过滤和limit?
不一定。现代MySQL优化器会执行子查询合并优化,它会自动把外层的过滤条件“下推”到内层的多表关联逻辑中,不会真的先把内层关联产生的所有数据都加载出来再做过滤。只有当子查询包含聚合、distinct或者某些无法被合并的特殊逻辑时,才会先执行内层查询生成临时表,再在外层做过滤。
2. 若将过滤条件和limit放入内层查询,是否性能更优?
select * from JOINS ON A LOT OF TABLES where col1="A" and col2="B" limit 100
从执行计划和实际性能来看,两种写法在优化器处理后基本等价。不过直接把过滤条件和limit写到多表关联语句里,写法更简洁直观,避免了冗余的子查询嵌套。当然如果子查询有特殊预处理逻辑,那另当别论,但单纯过滤+limit的场景,两种写法性能差异极小——你通过Workbench查询分析得到的一致结果也验证了这一点。
3. 使用having是否比where性能更差?
select * from JOINS ON A LOT OF TABLES having col1="A" and col2="B" limit 100
在这个无聚合操作的场景下,MySQL优化器会把having条件当作where条件来处理,执行计划完全一致,性能没有差异。但having的设计初衷是用来过滤聚合运算后的结果(比如配合sum()、count()等聚合函数),在无聚合的场景下用having属于用法不规范,会降低代码可读性,不推荐这么写。
内容的提问来源于stack exchange,提问作者Stalwart
相关产品推荐
相关产品推荐

