单次引用复杂查询结果优先选cte,因其轻量、可读性好且不占存储;临时表适用于多次引用、需建索引或跨语句共享数据的场景。

临时表和CTE到底该选哪个?
如果只是单次引用复杂查询结果,优先用 WITH(CTE),它更轻量、可读性好,且不占用额外存储。临时表真正有用的地方是:需要多次引用同一结果、要加索引、或需在多个语句间共享数据(比如后续做 UPDATE 或 JOIN)。别一上来就建临时表,多数场景 WITH 就够了。
SQL Server 里怎么安全创建本地临时表?
本地临时表名以单个 # 开头,只对当前会话可见,连接断开自动销毁。注意三点:
-
CREATE TABLE #temp后必须立刻INSERT INTO #temp SELECT ...,不能用SELECT ... INTO #temp在某些 SET 选项下报错(如ANSI_NULLS OFF) - 列名和类型由
SELECT推导,但隐式转换可能出错——比如VARCHAR(10)字段被截断却无警告 - 如果脚本可能并发执行,别依赖固定表名;改用
SELECT ... INTO #temp_<session_id></session_id>或直接用CREATE TABLE #temp (...) + INSERT
MySQL 8.0+ 临时表的坑:ENGINE 和生命周期
MySQL 的 CREATE TEMPORARY TABLE 默认用 MEMORY 引擎,但一旦字段含 TEXT、BLOB 或长度超限制,会静默退化为 InnoDB 临时表,性能差异极大。另外:
- 临时表只在当前连接内可见,但不会因事务回滚而消失——
DROP TEMPORARY TABLE或断开连接才释放 - 不能在存储过程中用相同名字反复
CREATE TEMPORARY TABLE,得先DROP;否则报错Table 'xxx' already exists - 如果 SELECT 中有用户变量(如
@rownum := @rownum + 1),写入临时表时行为不稳定,建议改用窗口函数
PostgreSQL 用 CREATE TEMP TABLE AS 的注意事项
PostgreSQL 不支持 SELECT ... INTO TEMP(那是旧语法,已弃用),统一用 CREATE TEMP TABLE AS SELECT。关键点:
- 生成的临时表默认无主键、无索引,大数据量 JOIN 前记得手动
CREATE INDEX ON pg_temp.xxx(...) - 临时表的 OID 和系统目录条目只存在于当前会话,但磁盘空间直到会话结束才回收——长事务中建大临时表可能撑爆
pg_temp目录 - 如果原始
SELECT里用了ORDER BY,临时表不保证顺序;需要排序必须在后续查询中显式写ORDER BY
COUNT(*) 结果塞进临时表,可能比原表还重。










