v$filestat仅提供file#、phyrds等原始io计数,不含文件名、路径或表空间信息,必须通过file#=file_id关联dba_data_files才能获得业务可读的统计结果。
直接查 v$filestat 就能拿到自实例启动以来每个数据文件的物理读写统计,但必须关联 dba_data_files 才能看出文件名和表空间,否则只有 file# 数字,毫无业务意义。
为什么不能只查 v$filestat 单独使用
视图里只有 file#、phyrds、phywrts 这类数字字段,没有文件路径、表空间名等可读信息。裸查会得到一堆编号和计数,根本不知道哪个文件对应哪个业务模块。
-
v$filestat不包含文件名、路径或表空间归属,纯 IO 计数器 - 多个数据文件可能共用同一
file#(比如 RAC 多实例下未加inst_id过滤) - 如果数据库启用了 ASM 或 ACFS,
file#和操作系统路径无直接映射关系
正确关联 dba_data_files 获取可读信息
必须用 file# = file_id 关联,这是唯一可靠的连接点。注意不是 file_name 或名字模糊匹配 —— 文件名可能被 rename 过,而 file_id 在控制文件中是稳定不变的。
SELECT df.tablespace_name, df.file_name, f.phyrds, f.phyblkrd, f.phywrts, f.phyblkwrt, ROUND(f.readtim / 100, 2) AS read_sec, ROUND(f.writetim / 100, 2) AS write_sec FROM v$filestat f JOIN dba_data_files df ON f.file# = df.file_id WHERE df.file_name IS NOT NULL ORDER BY f.phyblkrd DESC;
-
readtim和writetim单位是厘秒(centisecond),除以 100 得到秒级近似值 - 加
WHERE df.file_name IS NOT NULL排除临时文件或已删除但未清理元数据的条目 - RAC 环境下建议改用
gv$filestat并加inst_id过滤,否则会混入其他节点数据
PHYRDS 和 PHYBLKRD 差异大,说明什么
两者不相等是常态,不是错误。关键看比值:phyblkrd / phyrds 是平均每次物理读取的块数,反映多块读(如全表扫描)占比。
- 比值 ≈ 1:大量单块读,典型于索引查找、ROWID 访问,IO 散、延迟敏感
- 比值 > 8(甚至 128):高比例多块读,常见于大表扫描、并行查询,关注吞吐而非单次延迟
- 若
phyrds极高但phyblkrd很低,可能是频繁小读 + 缓存未命中,需检查 buffer cache 命中率
容易被忽略的限制与陷阱
v$filestat 统计的是“交由操作系统处理的 IO”,不是最终落盘次数。中间经过 OS buffer、存储缓存、ASM 条带等多层,尤其在 UFS 或 NFS 上,phyrds 可能只是文件系统缓存命中,并未真正触发磁盘寻道。
- 裸设备(raw device)或 ASM 磁盘组上的统计更贴近真实磁盘行为
-
time_statistics参数必须为TRUE,readtim/writetim才有值;默认可能关闭 - 该视图不统计重做日志文件(
v$log管理)、控制文件或归档日志 IO - 重启实例后所有计数清零,无法直接用于长期趋势分析,需自行采集快照对比











