视图查询时执行,临时表物化数据;视图是保存的select语句,每次调用重执行底层sql,临时表则将结果写入内存或磁盘供后续直接读取。

视图在查询时才执行,临时表会物化数据
视图本质是保存的 SELECT 语句,每次查询它都会重跑底层 SQL;临时表(如 CREATE TEMP TABLE)则会把结果真正写入内存或磁盘,后续查询直接读取已计算好的数据。这意味着:如果底层表很大、计算逻辑复杂(比如多层 JOIN + GROUP BY),反复查视图可能明显变慢;而临时表首次建表有开销,但之后多次读取更快。
常见错误现象:SELECT * FROM my_view WHERE status = 'done' 比直接写底层 SQL 慢几倍——不是因为视图语法有问题,而是优化器没能下推谓词,导致全量计算后再过滤。
- 适用场景:权限控制(用视图隐藏敏感字段)、封装常用查询逻辑、避免重复写长 SQL
- 不适用场景:需高频访问中间结果、要对结果做多次不同聚合、需要加索引加速后续查询
- PostgreSQL 中可配合
MATERIALIZED VIEW缓存结果,但需手动REFRESH;MySQL 不原生支持物化视图
临时表生命周期短,但能建索引和统计信息
临时表只在当前会话(或事务)中可见,断开连接即自动清理,这点比普通表安全,也比 CTE 更灵活——CTE 是“一次性”的,无法复用多次;临时表可以 SELECT、UPDATE、INSERT 多次,还能加索引提升后续操作效率。
典型使用场景:ETL 中清洗中间数据、分步调试复杂查询、替代游标做逐行处理(如循环更新一批记录)。
- MySQL 临时表默认在内存中(
ENGINE=MEMORY),但超限会落盘,注意tmp_table_size和max_heap_table_size配置 - PostgreSQL 临时表默认在
pg_temp_schema,自动走本地缓冲区,不参与 WAL,写入快但崩溃不持久 - SQL Server 的
#temp表支持统计信息自动更新,优化器能更好估算行数;而视图没有统计信息,容易选错执行计划
嵌套查询太深?优先考虑临时表而非多层视图
当业务需求演化出「视图 A 基于视图 B,B 又基于视图 C」这种链式依赖,性能会急剧下降:每层视图都可能阻止优化器重写或下推条件,最终执行计划变成嵌套子查询套娃,且难以 EXPLAIN 分析瓶颈点。
此时不如拆出来:用 CREATE TEMP TABLE AS SELECT ... 把关键中间结果固化,再基于它写后续逻辑。既清晰可控,又避免元数据膨胀(尤其在 PostgreSQL 中,大量视图会让 pg_views 查询变慢)。
- 不要为了“复用”强行抽象成视图——如果只有 1–2 处调用,直接写子查询或临时表更轻量
- 临时表名建议带业务前缀(如
tmp_user_active_7d),避免多人协作时命名冲突 - 显式
DROP TABLE IF EXISTS不是必须的(会话结束自动删),但脚本中加上更稳妥,尤其涉及重试逻辑时
小数据量用视图,大数据中间态必须用临时表
判断依据不是“看起来该不该复用”,而是看数据规模和访问模式。一个 SELECT COUNT(*) FROM orders WHERE created_at > now() - interval '1 day' 视图,每天只返回几百行,查十次也没压力;但若中间结果有 500 万行、还要连表关联三次,视图每次都会重新扫描主表并计算,IO 和 CPU 开销不可忽视。
真正容易被忽略的是统计信息同步问题:临时表刚创建时没有统计信息,首次查询可能走错执行计划(比如误判为小表而选 nested loop)。PostgreSQL 中可立即执行 ANALYZE temp_table_name;SQL Server 会在首次查询后自动更新,但 MySQL 的 MEMORY 引擎不支持统计信息,得靠经验预估。










