SQL嵌套查询如何避免全表扫描_合理使用索引辅助子查询
IN子查询变慢因MySQL 5.6前转为嵌套循环5.7需满足无GROUP BY等条件才启用半连接优化应改用EXISTS、确保索引或缓存结果。子查询里用 IN 为什么突然变慢因为 MySQL 5.6 之前IN (SELECT ...) 会被转成嵌套循环NLJ外层每行都执行一次子查询等价于全表扫描子查询表。5.7 虽支持半连接优化semi-join但前提是子查询不能含 GROUP BY、DISTINCT、聚合函数或相关子查询。检查执行计划看到 type: ALL 或 Extra: Using where; Using join buffer 就是危险信号把 IN (SELECT id FROM t2 WHERE ...) 改成 EXISTS (SELECT 1 FROM t2 WHERE t2.id t1.id AND ...)让优化器更可能走索引如果必须用 IN确保子查询结果集小且 t2.id 有索引——否则先用临时表缓存结果再 JOINWHERE 子句里写相关子查询索引还有效吗不一定。相关子查询correlated subquery每次都要重新计算如果子查询里没用上外层字段的索引条件就容易退化成对子表的重复全扫。典型陷阱SELECT * FROM orders WHERE status paid AND user_id IN (SELECT id FROM users WHERE region CN) —— 这里 users 表没被 orders 驱动region 索引可能被忽略改写优先级能 JOIN 就别用相关子查询JOIN 后加 WHERE 过滤比在子查询里过滤更易命中索引如果非用不可确保子查询中用于关联的字段如 users.id和过滤字段如 users.region都有联合索引比如 INDEX(region, id)子查询返回多列时SELECT * 会拖垮性能会。尤其是子查询作为派生表derived table出现在 FROM 子句时MySQL 会物化结果到临时表默认用 MyISAM旧版或 InnoDB8.0没索引、不压缩、全字段存储。 Cleanup.pictures 智能移除图片中的物体、文本、污迹、人物或任何不想要的东西