别人问你数据库的某个参数是多少时,一般我们都是会直接通过show parameter,或者select value from v$parameter的方式,但是这种查询只是查到的当前会话里的参数值,而如果这个会话对参数进行过修改的情况下,查出来的值与数据库实际的值其实是不一样的。
通过字典可以查到好多带有parameter的系统视图,比如V$PARAMETER,V$SPPARAMETER,V$SYSTEM_PARAMETER,以及V$PARAMETER2和V$SYSTEM_PARAMETER2等等,那这些视图之间到底有什么区别呢?
V$PARAMETER 
表示对于当前会话生效或正在起作用的参数值
V$SPPARAMETER 
它显示spfile内容的信息。 如果未使用spfile启动实例,则ISSPECIFIED列为FALSE。
V$SYSTEM_PARAMETER 
表示实例级别的参数信息,每开启一个新会话的时候,会话使用所有的参数都从这里进行继承。
V$PARAMETER2 
与V$PARAMETER 一样表示对于当前会话生效或正在起作用的参数值,稍有区别的是对于那些在V$PARAMETER 里的一个参数值里面有列表的情况,在本视图里就会显示成多行。
接下来会通过多个例子来详细说明他们之间的区别。
V$PARAMETER这个视图查到的结果与show parameter查到的一样,都是表示当前会话的值,我们可以通过执行计划来看到他们查到的是同样的fixed表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SQL> show parameter utl PARAMETER_NAME                                               TYPE        VALUE ------------------------------------------------------------ ----------- ---------------------------------------------------------------------------------------------------- create_stored_outlines                                       string utl_file_dir                                                 string ---------------------------------------------------------------------------------------------------------------- | Id  | Operation                  | Name             | E-Rows |E-Bytes| Cost (%CPU)|  OMem |  1Mem | Used-Mem | ---------------------------------------------------------------------------------------------------------------- |   0 | SELECT STATEMENT           |                  |        |       |     1 (100)|       |       |          | |   1 |  SORT ORDER BY             |                  |      1 |    57 |     1 (100)|  2048 |  2048 | 2048  (0)| |   2 |   COUNT                    |                  |        |       |            |       |       |          | |   3 |    NESTED LOOPS            |                  |      1 |    57 |     0   (0)|       |       |          | |*  4 |     FIXED TABLE FULL       | X$KSPPI          |     12 |   480 |     0   (0)|       |       |          | |*  5 |     FIXED TABLE FIXED INDEX| X$KSPPCV (ind:1) |      1 |    17 |     0   (0)|       |       |          | ---------------------------------------------------------------------------------------------------------------- 
可以看到执行show parameter时,查询到的X$KSPPI和X$KSPPCV,其中X$KSPPI主要用来存放参数的名称和描述,而X$KSPPCV主要用来表示当前值(CV = CURRENT VALUE)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 SQL> select value from v$parameter where name='utl_file_dir'; VALUE ------------- ----------------------------------------------------------------------------------- | Id  | Operation                | Name             | E-Rows |E-Bytes| Cost (%CPU)| ----------------------------------------------------------------------------------- |   0 | SELECT STATEMENT         |                  |        |       |     1 (100)| |   1 |  NESTED LOOPS            |                  |      1 |    54 |     0   (0)| |*  2 |   FIXED TABLE FIXED INDEX| X$KSPPI (ind:1)  |      1 |    37 |     0   (0)| |*  3 |   FIXED TABLE FIXED INDEX| X$KSPPCV (ind:1) |      1 |    17 |     0   (0)| ----------------------------------------------------------------------------------- 
通过比较可以看到二者查询的基表都一样,只是执行计划稍有区别。
而通过v$system_parameter去查询时,基表都变成了X$KSPPSV(SV = SYSTEM VALUE)
1 2 3 4 5 6 7 8 9 10 11 12 13 SQL> select value from v$system_parameter where name='utl_file_dir'; VALUE -------------------- ----------------------------------------------------------------------------------- | Id  | Operation                | Name             | E-Rows |E-Bytes| Cost (%CPU)| ----------------------------------------------------------------------------------- |   0 | SELECT STATEMENT         |                  |        |       |     1 (100)| |   1 |  NESTED LOOPS            |                  |      1 |    55 |     0   (0)| |*  2 |   FIXED TABLE FIXED INDEX| X$KSPPI (ind:1)  |      1 |    37 |     0   (0)| |*  3 |   FIXED TABLE FIXED INDEX| X$KSPPSV (ind:1) |      1 |    18 |     0   (0)| ----------------------------------------------------------------------------------- 
当一个会话里进行了某个参数修改后,其他会话查询这个视图是看不到修改结果的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 SQL> col value for a20 SQL> select value from v$parameter where name='session_cached_cursors'; VALUE -------------------- 50 SQL> alter session set session_cached_cursors=60; Session altered. SQL> select value from v$parameter where name='session_cached_cursors'; VALUE -------------------- 60 
而查看实例级别的参数值仍然是50
1 2 3 4 5 SQL> select value from v$system_parameter where name='session_cached_cursors'; VALUE -------------------- 50 
而V$SPPARAMETER里并没有设置这个参数
1 2 3 4 5 SQL> select value from v$spparameter where name='session_cached_cursors'; VALUE -------------------- 
如果将spfile里的参数进行修改后会发生什么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 SQL> alter system set session_cached_cursors=70 scope=spfile; System altered. SQL> select value from v$spparameter where name='session_cached_cursors'; VALUE -------------------- 70 SQL> select value from v$system_parameter where name='session_cached_cursors'; VALUE -------------------- 50 SQL> select value from v$parameter where name='session_cached_cursors'; VALUE -------------------- 60 
可以看到三者出现了完全不一样的值,因为这个实例是通过spfile启动的,所以重启实例看看会发生什么。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SQL> select value from v$system_parameter where name='session_cached_cursors'; VALUE -------------------- 70 SQL> select value from v$parameter where name='session_cached_cursors'; VALUE -------------------- 70 SQL> select value from v$spparameter where name='session_cached_cursors'; VALUE -------------------- 70 
三者都变成了spfile里设置的70,这是因为实例在启动的时候会去读取spfile的参数值,所以V$SYSTEM_PARAMETER的值就从50变成了70,而开启一个新会话是,V$PARAMETER就从实例参数里继承下来也变成了70。
对于部分参数值里有多个列表的的情况,V$PARAMETER2则可以将列表转换为多行。
1 2 3 4 5 6 7 8 9 10 11 12 SQL> select value from v$parameter where name='control_files'; VALUE -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /u01/app/oracle/oradata/ORA12C/controlfile/o1_mf_gcm27myg_.ctl, /u01/app/oracle/fast_recovery_area/ora12c/ORA12C/controlfile/o1_mf_gcm27ndj_.ctl SQL> select value from v$parameter2 where name='control_files'; VALUE -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /u01/app/oracle/oradata/ORA12C/controlfile/o1_mf_gcm27myg_.ctl /u01/app/oracle/fast_recovery_area/ora12c/ORA12C/controlfile/o1_mf_gcm27ndj_.ctl 
V$SYSTEM_PARAMETER2与V$SYSTEM_PARAMETER的区别也是如此。