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 JOINHASH JOINGROUP BYWINDOW SORTCREATE 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_HISTORY 或 V$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 等),我可以给出更精确的查询语句。