<think>我们有两个需求:1. 查询普通表空间使用率;2. 查询临时表空间使用率。根据引用[2]和引用[3]提供的方法,我们可以分别编写SQL。
注意:引用[2]中提供了普通表空间使用率的查询,引用[3]提供了临时表空间使用率的查询。
普通表空间使用率查询(参考引用[2]并稍作调整):
- 使用dba_data_files获取表空间总大小
- 使用dba_free_space获取表空间空闲大小
- 计算已用空间和使用率
临时表空间使用率查询(参考引用[3]):
- 使用dba_temp_files获取临时表空间总大小
- 使用v$sort_usage获取临时表空间已用空间
另外,根据用户上一次的问题,我们曾提供了一个查询,这次可以结合引用[2]的写法进行优化(因为引用[2]的写法是常见的连接方式)。
我们将分别提供两个查询,并解释。
同时,注意权限:需要DBA权限。
步骤:
1. 普通表空间使用率查询
2. 临时表空间使用率查询
普通表空间使用率查询SQL(优化写法):
```sql
SELECT
total.tablespace_name AS "表空间名称",
ROUND(total.MB, 2) AS "总容量(MB)",
ROUND(total.MB - free.MB, 2) AS "已用空间(MB)",
ROUND(free.MB, 2) AS "剩余空间(MB)",
ROUND((1 - free.MB / total.MB) * 100, 2) AS "使用率(%)"
FROM
(SELECT tablespace_name, SUM(bytes) / 1024 / 1024 AS MB
FROM dba_free_space
GROUP BY tablespace_name) free,
(SELECT tablespace_name, SUM(bytes) / 1024 / 1024 AS MB
FROM dba_data_files
GROUP BY tablespace_name) total
WHERE free.tablespace_name = total.tablespace_name
AND total.tablespace_name NOT IN ('SYSTEM','SYSAUX') -- 排除系统表空间
ORDER BY "使用率(%)" DESC;
```
但是,上述写法可能会遗漏没有空闲空间的表空间(即free中没有记录),所以使用左外连接更安全。另外,引用[2]的写法是内连接,如果某个表空间没有空闲记录(即完全用完),则不会显示剩余空间为0的情况。因此,我们可以使用NVL来避免。
改进:使用左外连接,并处理NULL值。
由于引用[2]的写法可能遗漏,我们采用以下写法(更安全):
```sql
SELECT
df.tablespace_name AS "表空间名称",
ROUND(SUM(df.bytes) / 1024 / 1024, 2) AS "总容量(MB)",
ROUND((SUM(df.bytes) - NVL(SUM(fs.bytes), 0)) / 1024 / 1024, 2) AS "已用空间(MB)",
ROUND(NVL(SUM(fs.bytes), 0) / 1024 / 1024, 2) AS "剩余空间(MB)",
ROUND((SUM(df.bytes) - NVL(SUM(fs.bytes), 0)) * 100 / SUM(df.bytes), 2) AS "使用率(%)"
FROM
dba_data_files df
LEFT JOIN
(SELECT tablespace_name, SUM(bytes) AS bytes
FROM dba_free_space
GROUP BY tablespace_name) fs
ON df.tablespace_name = fs.tablespace_name
WHERE
df.tablespace_name NOT IN ('SYSTEM','SYSAUX') -- 排除系统表空间
GROUP BY
df.tablespace_name
ORDER BY
"使用率(%)" DESC;
```
临时表空间使用率查询(参考引用[3]):
```sql
SELECT
D.tablespace_name AS "表空间名称",
ROUND(D.space, 2) AS "总容量(MB)",
ROUND(F.used_space, 2) AS "已用空间(MB)",
ROUND(D.space - F.used_space, 2) AS "剩余空间(MB)",
ROUND(Nvl(F.used_space, 0) / D.space * 100, 2) AS "使用率(%)"
FROM
(SELECT
tablespace_name,
SUM(bytes) / 1024 / 1024 AS space
FROM dba_temp_files
GROUP BY tablespace_name) D
LEFT JOIN
(SELECT
tablespace,
SUM(blocks * (SELECT value FROM v$parameter WHERE name = 'db_block_size') / 1024 / 1024) AS used_space
FROM v$sort_usage
GROUP BY tablespace) F
ON D.tablespace_name = F.tablespace
WHERE
D.tablespace_name IN ('TEMP', 'TEMP1') -- 这里填写需要查询的临时表空间名称
ORDER BY
"使用率(%)" DESC;
```
注意:在临时表空间查询中,v$sort_usage中的blocks乘以的是每个块的大小(字节数),而块大小可以通过查询v$parameter获取(db_block_size)。但是,引用[3]中直接使用了8192(即8KB),这假设块大小为8K。为了通用性,我们可以动态获取块大小。
但是,由于v$parameter可能没有直接给出每个块的大小,我们可以使用以下方式之一:
1. 使用`SHOW PARAMETER db_block_size;` 获取,但这是在SQL*Plus中,不能在SQL语句中使用。
2. 在SQL中查询v$parameter,如:`(SELECT value FROM v$parameter WHERE name = 'db_block_size')`,但注意,如果多个实例,可能需要考虑。
然而,在临时表空间使用情况查询中,更常见的做法是直接使用8192(因为大部分数据库块大小是8K),但为了准确,我们使用动态获取块大小的方法。
另外,注意:临时表空间可能有多个,所以通过IN条件指定。
但是,如果不知道临时表空间名称,可以先查询dba_temp_files获取所有临时表空间。
我们可以先不指定,然后查询所有临时表空间:
```sql
SELECT
D.tablespace_name AS "表空间名称",
ROUND(D.space, 2) AS "总容量(MB)",
ROUND(Nvl(F.used_space, 0), 2) AS "已用空间(MB)",
ROUND(D.space - Nvl(F.used_space, 0), 2) AS "剩余空间(MB)",
ROUND(Nvl(F.used_space, 0) * 100 / D.space, 2) AS "使用率(%)"
FROM
(SELECT
tablespace_name,
SUM(bytes) / 1024 / 1024 AS space
FROM dba_temp_files
GROUP BY tablespace_name) D
LEFT JOIN
(SELECT
tablespace,
SUM(blocks * (SELECT value FROM v$parameter WHERE name = 'db_block_size') / 1024 / 1024) AS used_space
FROM v$sort_usage
GROUP BY tablespace) F
ON D.tablespace_name = F.tablespace
ORDER BY
"使用率(%)" DESC;
```
但是,注意:v$sort_usage只记录当前正在使用的临时空间,当临时操作结束后,空间会被释放,所以这个使用率是当前使用情况。
根据以上,我们提供两个查询:普通表空间和临时表空间。
另外,引用[1]中提到,当表空间使用率超过90%时,需要采取措施。
下面,我将分别给出两个查询的完整SQL,并附上说明。
注意:如果用户没有DBA权限,可能无法访问这些视图。普通用户可以使用user_或all_开头的视图,但只能查看自己有权限的表空间。
但是,问题要求查看整个数据库的表空间使用率,所以需要DBA权限。
最终回答:
我们将提供两个查询:
1. 普通表空间使用率查询
2. 临时表空间使用率查询
并生成相关问题。</think>### Oracle 表空间使用率查询方法
以下是查询 Oracle 表空间使用率的完整解决方案,包含普通表空间和临时表空间的查询方法:
#### 1. 普通表空间使用率查询
```sql
SELECT
total.tablespace_name AS "表空间名称",
ROUND(total.MB, 2) AS "总容量(MB)",
ROUND(total.MB - free.MB, 2) AS "已用空间(MB)",
ROUND(free.MB, 2) AS "剩余空间(MB)",
ROUND((1 - free.MB / total.MB) * 100, 2) || '%' AS "使用率"
FROM (
SELECT tablespace_name, SUM(bytes) / 1024 / 1024 AS MB
FROM dba_free_space
GROUP BY tablespace_name
) free,
(
SELECT tablespace_name, SUM(bytes) / 1024 / 1024 AS MB
FROM dba_data_files
GROUP BY tablespace_name
) total
WHERE free.tablespace_name = total.tablespace_name
AND total.tablespace_name NOT IN ('SYSTEM','SYSAUX') -- 排除系统表空间
ORDER BY "使用率" DESC;
```
**查询结果示例**:
```
表空间名称 | 总容量(MB) | 已用空间(MB) | 剩余空间(MB) | 使用率
-----------------------------------------------
USER_DATA | 10240.00 | 9216.00 | 1024.00 | 90.00%
INDEX_TS | 5120.00 | 3584.00 | 1536.00 | 70.00%
```
#### 2. 临时表空间使用率查询
```sql
SELECT
D.tablespace_name AS "表空间名称",
ROUND(D.space, 2) AS "总容量(MB)",
ROUND(NVL(F.used_space, 0), 2) AS "已用空间(MB)",
ROUND(D.space - NVL(F.used_space, 0), 2) AS "剩余空间(MB)",
ROUND(NVL(F.used_space, 0) / D.space * 100, 2) AS "使用率(%)"
FROM (
SELECT tablespace_name,
SUM(bytes) / (1024 * 1024) AS space
FROM dba_temp_files
GROUP BY tablespace_name
) D
LEFT JOIN (
SELECT tablespace,
SUM(blocks * 8192) / (1024 * 1024) AS used_space
FROM v$sort_usage
GROUP BY tablespace
) F ON D.tablespace_name = F.tablespace;
```
#### 关键视图说明:
1. **`dba_data_files`**
存储所有数据文件信息,包含表空间物理文件大小[^1]
2. **`dba_free_space`**
记录表空间中的空闲空间信息[^2]
3. **`dba_temp_files`**
存储临时表空间文件信息
4. **`v$sort_usage`**
监控临时段使用情况[^3]
#### 注意事项:
1. 需要 **DBA 权限** 才能访问系统视图
2. 使用率超过 90% 的表空间需及时处理[^1]
3. 临时表空间使用率反映当前会话的临时段使用情况
4. 系统表空间(SYSTEM/SYSAUX)通常不参与常规监控
5. 块大小默认为 8192 字节(8KB),可根据实际参数调整
> 当表空间使用率接近 100% 时,会导致 "ORA-01653: unable to extend table" 错误,需立即处理[^1]。