当前位置: 代码网 > it编程>数据库>MsSqlserver > SQL中的Subquery & CTE & Temporary Table 区别深度对比分析

SQL中的Subquery & CTE & Temporary Table 区别深度对比分析

2025年05月06日 MsSqlserver 我要评论
subquery、cte 和 temporary table 的深度对比这三个技术都用于创建临时数据集,但它们在实现方式、使用场景和性能特点上有显著差异。让我们用"数学演草纸"的比

subquery、cte 和 temporary table 的深度对比

这三个技术都用于创建临时数据集,但它们在实现方式、使用场景和性能特点上有显著差异。让我们用"数学演草纸"的比喻来深入分析:

1. 子查询 (subquery)

比喻:就像在解题过程中随手在题目旁边写的草稿计算

特点

  • 内联性:直接嵌套在sql语句中(select/from/where等子句内)
  • 一次性使用:定义后只能在该处使用一次
  • 无命名:通常没有显式的名称(除非是派生表)
  • 作用域:仅在包含它的查询中有效

示例

select user_id 
from orders 
where amount > (select avg(amount) from orders);  -- where子句中的子查询

适用场景

  • 简单的单次使用计算
  • 作为过滤条件或比较值
  • 快速测试不需要复用的逻辑

2. 公共表表达式 (cte, common table expression)

比喻专门拿出一张草稿纸写中间步骤,可以随时翻看

特点

  • 显式命名:使用with cte_name as语法定义
  • 可复用性:在同一个with子句中可定义多个cte,且后面的cte可以引用前面的
  • 查询级作用域:仅在紧随其后的单个sql语句中有效
  • 可递归:支持递归查询(处理层次结构数据)

示例

-- 使用cte和比较运算符 >,先筛选出消费总额超过1000的高价值用户和最近30天活跃用户,最终通过 intersect 取两者的交集,找出​​既高消费又活跃的核心用户群体​​。
with high_value_customers as (
    select user_id from orders group by user_id having sum(amount) > 1000
), #筛选订单总额超过1000的用户
active_customers as (
    select user_id from logins where login_date > current_date - 30
) #筛选30天内有登录记录的活跃用户
select * from high_value_customers 
intersect 
select * from active_customers;

适用场景

  • 复杂查询的模块化设计
  • 需要多次引用同一结果集
  • 递归查询
  • 提高复杂查询的可读性

3. 临时表 (temporary table)

比喻:专门准备一个笔记本记录中间结果,可以反复翻阅和修改

特点

  • 物理存储:实际存储在tempdb中(内存或磁盘)
  • 会话级作用域:创建后在整个会话期间可用,直到显式删除或会话结束
  • 可索引:可以添加索引优化性能
  • 可修改:支持insert/update/delete操作
  • 跨查询使用:可以被同一会话的多个查询使用

示例

create temporary table temp_high_value as
select user_id from orders group by user_id having sum(amount) > 1000;
alter table temp_high_value add index (user_id);  -- 可以添加索引
select * from temp_high_value h join users u on h.user_id = u.id;
drop temporary table if exists temp_high_value;  -- 显式清理

适用场景

  • 复杂的etl流程
  • 需要多次重用的中间结果
  • 大型数据集处理(特别是需要索引优化时)
  • 跨多个sql语句共享数据

三者的核心对比

特性子查询 (subquery)cte临时表 (temporary table)
存储方式逻辑存在,不物理存储逻辑存在,可能被优化器物化物理存储在tempdb
作用域当前子句当前语句整个会话
生命周期查询执行期间查询执行期间显式删除或会话结束
是否可复用不可复用同一with子句内可引用跨查询复用
是否可修改不可修改不可修改可insert/update/delete
是否支持索引不支持不支持支持
性能特点简单查询高效中等复杂度查询最优复杂数据处理最优
语法复杂度简单中等较高
典型使用场景简单过滤/计算复杂查询模块化跨语句共享数据/大型处理

如何选择?

  • 简单计算 → 子查询
  • 中等复杂度查询 → cte(提高可读性)
  • 需要多次引用/修改 → 临时表
  • 递归查询 → cte with recursive
  • 会话级重用 → 临时表

记住:随着sql复杂度的增加,通常的开发路径是:子查询 → cte → 临时表。优化器对三者的处理方式不同,在性能关键场景中需要测试验证。

到此这篇关于sql中的subquery & cte & temporary table 区别深度对比分析的文章就介绍到这了,更多相关sql subquery、cte 和 temporary table内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com