Oracle-表空间temp

sql 复制代码
SELECT 
    sql_id,
    child_number,
    operation,
    options,
    object_name,
    bytes,
    temp_space
FROM v$sql_plan_statistics_all
WHERE sql_id = '你的SQL_ID'
  AND temp_space IS NOT NULL; 这段SQL里temp_space都为空阿?还有就是bytes字段 是啥意思 是不是就是所在的临时空间大小

你提出的问题非常典型,很多 Oracle 开发者在使用 v$sql_plan_statistics_all 视图时都会遇到类似困惑。我们来逐一解答:


❓ 问题一:为什么 temp_space 字段总是 NULL

✅ 原因如下:

1. temp_space 是"预估"值,不是实际运行时的值

  • 它来源于 执行计划(Execution Plan)中的 CBO(Cost-Based Optimizer)估算
  • 如果优化器认为该操作不需要临时空间(比如排序可以在内存完成),就不会填这个字段。
  • 即使 SQL 实际运行时用了临时表空间(如发生磁盘排序),temp_space 仍可能为 NULL,因为它只反映"计划阶段"的估算。

📌 关键点temp_space ≠ 实际使用的临时空间,而是"优化器预计需要多少"。


2. 只有部分操作会填充 temp_space

通常只有以下操作可能有非空 temp_space

  • SORT JOIN
  • HASH JOIN
  • GROUP BY
  • WINDOW SORT
  • CREATE TABLE AS SELECT

但即使如此,如果数据量小、PGA 足够,Oracle 可能完全在内存处理,不分配 temp 段,于是 temp_space = NULL


3. 统计信息缺失或过期

如果表没有收集统计信息,CBO 无法准确估算中间结果集大小,也可能导致 temp_space 为空。


❓ 问题二:bytes 字段是什么意思?是不是临时空间大小?

不是!

bytes 的真实含义:

  • 表示 该操作预计输出的数据量(字节数),即"从这一步返回多少数据"。
  • 来源于 CBO 对 基数(Cardinality) × 平均行长度(Avg Row Len) 的估算。
  • 与临时表空间无关,只是数据流的大小预估。

举例:

如果一个 HASH JOIN 输出 100 万行,每行平均 100 字节,则 bytes ≈ 100,000,000

但这并不等于它用了 100MB 临时空间------实际 temp 使用取决于是否溢出到磁盘。


✅ 那么,如何真正查看 SQL 实际用了多少临时空间

推荐方法:使用 V$SQL + V$ACTIVE_SESSION_HISTORYV$SORT_USAGE

方法 1:查已执行 SQL 的实际 temp 使用(Oracle 12c+)
sql 复制代码
SELECT 
    sql_id,
    sql_text,
    ROUND(temp_space_allocated / 1024 / 1024, 2) AS temp_mb_used
FROM v$sql
WHERE sql_id = '你的SQL_ID'
  AND temp_space_allocated > 0;

temp_space_allocated实际分配的临时空间(字节),这是最可靠的指标(12c 及以上支持)。


方法 2:通过会话实时监控(适用于正在运行的 SQL)
sql 复制代码
SELECT 
    s.sid,
    s.serial#,
    s.sql_id,
    su.tablespace,
    su.segtype,
    su.blocks * t.block_size AS temp_bytes_used
FROM v$sort_usage su
JOIN v$session s ON su.session_addr = s.saddr
JOIN dba_tablespaces t ON t.tablespace_name = su.tablespace
WHERE s.sql_id = '你的SQL_ID';

这个结果是 真实使用的临时段大小,单位是字节。


方法 3:使用 AWR 报告(历史分析)

如果你有 DBA 权限,可查:

sql 复制代码
SELECT 
    sql_id,
    plan_hash_value,
    SUM(temp_space_allocated_total) / NULLIF(SUM(executions_total), 0) AS avg_temp_bytes
FROM dba_hist_sqlstat
WHERE sql_id = '你的SQL_ID'
GROUP BY sql_id, plan_hash_value;

🔚 总结

字段 含义 是否反映实际 temp 使用
temp_space 优化器预估的临时空间需求 ❌ 否(常为 NULL)
bytes 操作输出数据量预估 ❌ 否
v$sql.temp_space_allocated 实际分配的临时空间(12c+) ✅ 是
v$sort_usage.blocks 当前会话真实使用的 temp 段块数 ✅ 是

💡 建议

  • 如果你用的是 Oracle 12c 或更高版本 ,直接查 v$sql.temp_space_allocated 最简单。
  • 如果是 11g ,只能通过 v$sort_usage 监控运行中的会话,或通过前后快照对比。

如需进一步帮助,请告知你的 Oracle 版本(如 11.2.0.4、19c 等),我可以给出更精确的查询语句。

相关推荐
wuyk55539 分钟前
【Socket 进阶之路】第 7 章 IO 多路复用 select & poll 完整实战|多 fd 监听、超时等待、优缺点横向对比
服务器·开发语言·网络·数据库·物联网
文人sec1 小时前
grant 之后要跟着 flush privileges 吗?要不要使用分区表?
数据库·mysql·adb·数据分析
Omics Pro1 小时前
上海AI Lab孙思琦×高张阳:虚拟细胞代码库智能体
数据库·人工智能·算法·机器学习·自然语言处理
点纭2 小时前
C 语言 第七章 常用函数(3)
c语言·开发语言·算法·oracle·c#
旺仔不是程序员2 小时前
相关子查询与性能优化:PostgreSQL 逐行执行的代价与 JOIN 重写
数据库·后端·sql
YangYang9YangYan2 小时前
2026 电商数据运营校招 JD 梳理|岗位任务、技能与面试考点汇总
大数据·数据库·数据分析
Sun 32852 小时前
读懂集中式主备的集群状态与节点角色
数据库·opengauss·集群·节点角色·磐维数据库·运行状态
努力努力再努力wz3 小时前
【Redis进阶系列】:从主从复制到 Sentinel,一文建立故障检测、Leader 选举与 Failover 的完整心智模型
数据库·redis·缓存
达梦数据3 小时前
DMDRS搭建部署简介与运行环境
数据库
Omics Pro3 小时前
1个月2轮融资!长寿虚拟细胞
数据库·人工智能·算法·机器学习·自然语言处理