通过set autotrace 的执行计划看出查询v$filestat实际上是查询了X$KCFIO,X$KCCFE
SQL> set autotrace on;
SQL> Select file#,phyrds,phywrts from v$filestat;
FILE# PHYRDS PHYWRTS
----- ---------- ----------
1 175397 12846
2 6838 41451
3 102878 51928
4 722 81
5 983802 19167
6 310961 16126
7 339664 18688
8 204042 16283
9 27524 436
10 26169 647
......
22 -1509449799 4298715
......
执行计划
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 78 | 0 (0)
| 1 | NESTED LOOPS | | 1 | 78 | 0 (0)
| 2 | FIXED TABLE FULL | X$KCFIO | 1 | 52 | 0 (0)
| 3 | FIXED TABLE FIXED INDEX| X$KCCFE (ind:1) | 1 | 26 | 0 (0)
--------------------------------------------------------------------------------
Note
-----
- 'PLAN_TABLE' is old version
统计信息
----------------------------------------------------
8 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
834 bytes sent via SQL*Net to client
257 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
34 rows processed
-- v$fixed_view_definition中看出V$FILESTAT是基于GV$FILESTAT的视图
SQL> select * from v$fixed_view_definition where VIEW_NAME = 'V$FILESTAT';
VIEW_NAME
------------------------------
VIEW_DEFINITION
--------------------------------------------------------------------------------
V$FILESTAT
select FILE# , PHYRDS , PHYWRTS , PHYBLKRD , PHYBLKWRT , SINGLEBLKRDS, READTIM
, WRITETIM, SINGLEBLKRDTIM, AVGIOTIM, LSTIOTIM, MINIOTIM, MAXIORTM, MAXIOWTM f
rom GV$FILESTAT where inst_id = USERENV('Instance')
-- 而GV$FILESTAT是由x$kcfio k,x$kccfe创建的视图
SQL> select * from v$fixed_view_definition where VIEW_NAME='GV$FILESTAT';
VIEW_NAME
------------------------------
VIEW_DEFINITION
--------------------------------------------------------------------------------
GV$FILESTAT
select k.inst_id, k.kcfiofno,k.kcfiopyr,k.kcfiopyw,k.kcfiopbr,k.kcfiopbw, k.kcfi
osbr,k.kcfioprt,k.kcfiopwt,k.kcfiosbt,k.kcfioavg,k.kcfiolst,k.kcfiomin, k.kcfior
mx,k.kcfiowmx from x$kcfio k,x$kccfe f where f.fedup <> 0 and f.fenum=k.kcfiofno
这个就是访问V$FILESTAT 在执行计划中看到x$kcfio k,x$kccfe 表的原因,
因为V$FILESTAT是基于x$kcfio k,x$kccfe 定义的。
--可以看出 X$KCFIO中 KCFIOPYR是NUMBER类型的
SQL> desc X$KCFIO
名称 是否为空? 类型
------------- -------- ------------
ADDR RAW(8)
INDX NUMBER
INST_ID NUMBER
KCFIOFNO NUMBER
KCFIOPYR NUMBER
KCFIOPYW NUMBER
KCFIOSBR NUMBER
KCFIOPRT NUMBER
KCFIOPWT NUMBER
KCFIOSBT NUMBER
KCFIOPBR NUMBER
KCFIOPBW NUMBER
KCFIOCRTR NUMBER
KCFIOCURTR NUMBER
KCFIOAVG NUMBER
KCFIOLST NUMBER
KCFIOMIN NUMBER
KCFIORMX NUMBER
KCFIOWMX NUMBER
KCFIOMBR NUMBER
KCFIOMBT NUMBER
KCFIOCTS NUMBER
-- v$filestat中PHRDS也是NUMBER类型
SQL> desc v$filestat
名称 是否为空? 类型
---------------- -------- --------
FILE# NUMBER
PHYRDS NUMBER
PHYWRTS NUMBER
PHYBLKRD NUMBER
PHYBLKWRT NUMBER
SINGLEBLKRDS NUMBER
READTIM NUMBER
WRITETIM NUMBER
SINGLEBLKRDTIM NUMBER
AVGIOTIM NUMBER
LSTIOTIM NUMBER
MINIOTIM NUMBER
MAXIORTM NUMBER
MAXIOWTM NUMBER
oracle文档中对PHYRDS的解释是Number of physical reads done
我理解为物理读的数量。理论上应该不是负值。出现了负值我认为应该:
1.分散IO.
可能是这个数据文件上的物理读太多了,把这个数据文件上的表move到其它的表空间一部分。
2.优化SQL
找到这个表空间全表扫描多的sql,进行优化。