This Blog will try to do expose meta data of x$ tables since they are not handled in a uniform way as normal tables. We also take GV$SQL_OPTIMIZER_ENV and its underlined X$KQLFSQCE as example in the queries because this x$ table is dynamic, big, and longer duration of its stats gathering.
1. List all fixed objects
select * from x$kqfta fxt, sys.fixed_obj$ fobj where fobj.obj# = fxt.kqftaobj and fxt.kqftanam in ('X$KQLFSQCE');
2. List indexes of fixed objects
select index_number, column_name from gv$indexed_fixed_column where table_name in ('X$KQLFSQCE');
1 KQLFSQCE_HASH
2 KQLFSQCE_SQLID
We can try to verify them by looking the xplan of following queries:
select * from gv$sql_optimizer_env where hash_value = :hash_value;
FIXED TABLE FIXED INDEX TABLE (FIXED) SYS.X$KQLFSQCE (ind:1)
select * from gv$sql_optimizer_env where sql_id = :sql_id;
FIXED TABLE FIXED INDEX TABLE (FIXED) SYS.X$KQLFSQCE (ind:2)
select * from gv$sql_optimizer_env where id = :id; (KQLFSQCE_PNUM)
FIXED TABLE FULL TABLE (FIXED) SYS.X$KQLFSQCE
3. List histogram of fixed objects
select column_name, histogram from dba_tab_col_statistics
where table_name in ('X$KQLFSQCE') and histogram not in ('NONE');
INST_ID FREQUENCY
KQLFSQCE_FLAGS FREQUENCY
select distinct table_name, column_name from dba_tab_histograms where table_name in ('X$KQLFSQCE');
INST_ID
KQLFSQCE_FLAGS
select dbms_stats.report_gather_fixed_obj_stats(detail_level=>'ALL', format=>'TEXT') from dual;
INST_ID
KQLFSQCE_HADD
KQLFSQCE_SQLID
KQLFSQCE_FLAGS
KQLFSQCE_PNUM
The above 3 outputs have differences, and we can try to verify them by looking the xplan of following queries:
select * from gv$sql_optimizer_env where inst_id = 1;
FIXED TABLE FULL TABLE (FIXED) SYS.X$KQLFSQCE QBlock Name: SEL$5C160134
Cost: 1 Bytes: 32,349,932 Cardinality: 376,162
select * from gv$sql_optimizer_env where inst_id = 9;
FIXED TABLE FULL TABLE (FIXED) SYS.X$KQLFSQCE QBlock Name: SEL$5C160134
Cost: 1 Bytes: 86 Cardinality: 1
select * from gv$sql_optimizer_env where id = 1;
FIXED TABLE FULL TABLE (FIXED) SYS.X$KQLFSQCE QBlock Name: SEL$5C160134
Cost: 1 Bytes: 68,800 Cardinality: 800
select * from gv$sql_optimizer_env where id = 9;
FIXED TABLE FULL TABLE (FIXED) SYS.X$KQLFSQCE QBlock Name: SEL$5C160134
Cost: 1 Bytes: 68,800 Cardinality: 800
We can see that two queries on column ID (KQLFSQCE_PNUM) give the same xplan estimation, probably does not have histogram.
It is not clear why dbms_stats.report_gather_fixed_obj_stats lists more columns.
4. List stats gathering performance of fixed tables
select v.last_analyzed, table_name, num_rows, sample_size, avg_row_len
,(v.last_analyzed - lag(v.last_analyzed) over (order by v.last_analyzed))*86400 seconds
,(num_rows * avg_row_len) bytes
,(sample_size/nullif(num_rows, 0)) sample_ratio
,v.*
from dba_tab_statistics v
where object_type in ('FIXED TABLE')
and v.last_analyzed between timestamp'2016-05-17 09:00:00' and timestamp'2016-05-17 10:00:00'
order by seconds desc nulls last;
As a result of above query, we can find the most time consuming of x$ tables in:dbms_stats.gather_fixed_objects_stats;
and hence exclude them in next stats gather by calling
dbms_stats.lock_table_stats
5. Trace x$ table access
On Solaris, run:
exec dbms_stats.gather_fixed_objects_stats;
and simultaneously watch kqlfsqce call by dtrace script (8694 is PID of above SQL Session):
sudo dtrace -n \
'BEGIN {printf("dtrace started: %Y\n", walltimestamp);}
pid8694:a.out:kqlfsqce: { @[execname, ustack()] = count();}
END { trunc(@, 10);}
END { printf("dtrace ended: %Y\n", walltimestamp);}'
and stop the tracing once X$KQLFSQCE is gathered, the output looks as:
dtrace: description 'BEGIN ' matched 111 probes
CPU ID FUNCTION:NAME
17 1 :BEGIN dtrace started: 2016 May 17 09:13:01
^C
21 2 :END
21 2 :END dtrace ended: 2016 May 17 09:42:42
oracle
oracle`kqlfsqce+0x2c
oracle`qerfxFetch+0x125f
oracle`rwsfcd+0x6f
oracle`qeruaFetch+0x173
oracle`rwsfcd+0x6f
oracle`qerltFetch+0x4c8
oracle`insdlexe+0x202
oracle`insExecStmtExecIniEngine+0x6b
oracle`insexe+0x6eb
oracle`opiexe+0x179f
oracle`opipls+0x62a
oracle`opiodr+0x433
oracle`rpidrus+0xde
oracle`skgmstack+0x85
oracle`rpidru+0x88
oracle`rpiswu2+0x2fd
oracle`rpidrv+0x589
oracle`psddr0+0x138
oracle`psdnal+0x2cd
oracle`pevm_EXIM+0xf0
3290001
Crosschecking with output of above sql query, the row for X$KQLFSQCE shows:
sample_size = 3281070
seconds = 1736