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 等),我可以给出更精确的查询语句。

相关推荐
GuWenyue1 小时前
Cursor黑盒拆解!1套LangChain.js手写Mini编程Agent,自动生成React项目,效率提升60%
前端·数据库·人工智能
Miao121313 小时前
某海外住宿平台如何在大规模场景下实现指标一致性:Minerva 指标平台实践
大数据·数据库·人工智能
CodexDave3 小时前
MySQL事务隔离级别与MVCC机制解析
前端·数据库·mysql·nginx·性能优化·负载均衡
碎光拾影3 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
曾阿伦3 小时前
MongoDB 查询语句备忘手册
数据库·mongodb
一叶龙洲3 小时前
wslg打开Ubuntu24.04默认打开图形界面
linux·服务器·数据库·ubuntu
CCPC不拿奖不改名3 小时前
大模型推理架构与开源生态知识整理
数据库·windows·python·架构·langchain·开源·github
爬也要爬着前进5 小时前
redis主从搭建
数据库·redis·缓存
@Mike@5 小时前
02-数据库学习笔记(SQL引擎)
数据库·笔记·学习
踏月的造梦星球7 小时前
达梦数据库执行计划与性能分析入门:EXPLAIN、AUTOTRACE 与 ET
服务器·数据库·oracle