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

相关推荐
x***r15111 小时前
Redis Desktop Manager 0.8.8 安装教程(Windows redis-desktop-manager-0.8.8.384详细步骤)
数据库·windows·redis
initialize130611 小时前
Postgresql(Oracle兼容) 到Oracle19.9字符语义
数据库·oracle
稷下元歌12 小时前
七天学会plc 加机器视觉完整笔记:S7-1200 数据类型、存储区与寻址方式(I/Q/M/DB 详解)。
网络·数据库·笔记
潮起鲸落入海12 小时前
mysql 5.x源码安装
数据库·mysql
phltxy12 小时前
MCP 从协议到 Spring AI 实战
人工智能·spring·oracle
睡不醒男孩03082312 小时前
第一篇:多云与多模态时代的企业级数据库云管理平台(DBaaS)选型指南
数据库·clup·中启乘数
小二·13 小时前
向量数据库实战
数据库
炘爚13 小时前
Phase 5:MySQL 连接池
数据库·mysql
j_xxx404_13 小时前
MySQL库操作硬核解析:字符集、校验规则、大小写比较、备份恢复与连接排查
运维·服务器·数据库·人工智能·mysql·ai·oracle
minji...14 小时前
MySQL数据库 (五) MySQL表的约束(上),非空约束,默认值约束,零填充约束,主键约束,符合主键
数据库·mysql·表的约束·主键约束·非空约束·复合主键·零填充约束