讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在SQL中编写高效的嵌套查询以减少IO开销?

夜强君_7011

夜强君_7011

发布时间:2026-06-29 09:53:47

|

585人浏览过

|

来源于php中文网

原创

嵌套查询本身不是问题,但写法不当会放大IO:JOIN或WHERE中对列用函数(如UPPER、DATE、id+1)导致索引失效而全表扫描;子查询未改写为JOIN易引发多次执行;SELECT *层层包裹增加冗余字段传输;ORDER BY LIMIT置于内层无法下推,应放最外层。

如何在sql中编写高效的嵌套查询以减少io开销?

嵌套查询本身不是问题,但写法不当会直接放大IO——尤其在JOIN字段或WHERE里用函数、SELECT *层层包裹、ORDER BY LIMIT塞进内层时,数据库往往被迫反复读磁盘。

别在JOIN或WHERE里对列用函数

比如 UPPER(name)、DATE(create_time)、id + 1 这类表达式出现在关联条件或过滤中,会让索引彻底失效。MySQL、PostgreSQL、SQL Server 都无法走索引查找,只能全表扫描两遍再比对。

  • 错误写法:LEFT JOIN user_info ON UPPER(u.name) = UPPER(i.name) —— 两个表都得算一遍UPPER()
  • 正确做法:提前建规范列,如 name_upper VARCHAR(64),加索引,并在业务写入时同步维护
  • 替代方案:用大小写不敏感排序规则,如 MySQL 8.0+ 的 COLLATE utf8mb4_0900_as_cs,避免运行时计算
  • 验证方式:用 EXPLAIN 看 type 是 ref 还是 ALL;key 列是否非 NULL

把子查询改写成JOIN,尤其IN/EXISTS场景

像 SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE region = 'CN') 这种,在 MySQL 5.7 或旧版 PostgreSQL 中极易被优化器判为“相关子查询”,导致外层每行都执行一次内层,IO翻N倍。

  • 优先改写为 INNER JOIN customers c ON o.customer_id = c.id WHERE c.region = 'CN'
  • 如果子查询含 LIMIT 或 GROUP BY 无法直转,用 CTE 强制物化:WITH cust AS (SELECT id FROM customers WHERE region = 'CN' LIMIT 100) SELECT * FROM orders WHERE customer_id IN (SELECT id FROM cust)
  • MySQL 8.0 用户可开启 semijoin=on(通过 SET optimizer_switch='semijoin=on'),让优化器更倾向合并子查询

每一层只选真正需要的字段

SELECT * FROM (SELECT * FROM (SELECT * FROM t1 JOIN t2) t23) t34 看似方便,实则让中间结果集携带大量无用字段,加重网络传输、内存拷贝和缓冲区压力——尤其当某层只用 id 和 status 做后续过滤时,其他字段纯属IO浪费。

  • 逐层精简:SELECT id, status FROM t1 JOIN t2 ON ... → 外层只基于这两列继续操作
  • 给子查询结果起明确别名,避免 Column 'xxx' in field list is ambiguous
  • PostgreSQL 下可用 EXPLAIN (ANALYZE, BUFFERS) 观察 Shared Hit Blocks 是否异常高,判断是否因冗余字段拖慢缓存命中

ORDER BY + LIMIT 必须放在最外层

把 ORDER BY create_time DESC LIMIT 10 写进子查询里,看起来能早剪枝,但多数数据库(MySQL 5.7、SQL Server)无法保证排序上下文穿透多层嵌套,结果可能错乱,且优化器常无法下推LIMIT到物理扫描阶段,反而多扫一遍再排序。

  • 正确位置:SELECT ... FROM (...) t ORDER BY create_time DESC LIMIT 10
  • 前提是 create_time 有索引,否则仍会触发文件排序(Using filesort)
  • 若需分页深度较大(如 LIMIT 10000, 10),考虑用延迟关联:SELECT p.* FROM posts p JOIN (SELECT id FROM posts WHERE ... ORDER BY create_time LIMIT 10000, 10) tmp USING (id)

真正卡IO的地方,往往不在“要不要嵌套”,而在于每层是否清楚自己只需要什么、是否让数据库有机会用上索引、是否把排序和裁剪留到了最后一步。这些点漏掉任何一个,都可能让10万行查询变成秒级响应或数十秒等待。

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

3803

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

811

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

989

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

5621

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2583

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

5600

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

7361

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1010

2024.04.29

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

120

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL索引优化解决方案
MySQL索引优化解决方案

共23课时 | 2.7万人学习

SQL优化与排查(MySQL版)
SQL优化与排查(MySQL版)

共26课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn