從Oracle9i開始,爲了監控column的使用信息,引入了一個對象col_usage$,用於記錄運行時的COLUMN使用信息。
這部分信息由SMON維護,因此當看到SMON報出相關的死鎖、錯誤時不要驚訝,SMON作的工做是愈來愈雜了。
在Oracle10g中,這個表的結構以下:數據庫
create table col_usage$ ( obj# number, /* object number */ intcol# number, /* internal column number */ equality_preds number, /* equality predicates */ equijoin_preds number, /* equijoin predicates */ nonequijoin_preds number, /* nonequijoin predicates */ range_preds number, /* range predicates */ like_preds number, /* (not) like predicates */ null_preds number, /* (not) null predicates */ timestamp date /* timestamp of last time this row was changed */ ) storage (initial 200K next 100k maxextents unlimited pctincrease 0) / create unique index i_col_usage$ on col_usage$(obj#,intcol#) storage (maxextents unlimited) /
注意,這裏的每一個選項都是有意義的,好比maxextents unlimited就是由於col_usage$表可能過分擴展空間設計的。
今天,在客戶一個繁忙的數據庫中,看到了關於這個表的操做SQL,執行次數很是頻繁,如下是3個SQL:
ui
LOCK TABLE SYS.col_usage$ IN EXCLUSIVE MODE NOWAIT; UPDATE SYS.col_usage$ SET equality_preds = equality_preds + DECODE (BITAND (:flag, 1), 0, 0, 1), equijoin_preds = equijoin_preds + DECODE (BITAND (:flag, 2), 0, 0, 1), nonequijoin_preds = nonequijoin_preds + DECODE (BITAND (:flag, 4), 0, 0, 1 ), range_preds = range_preds + DECODE (BITAND (:flag, 8), 0, 0, 1), like_preds = like_preds + DECODE (BITAND (:flag, 16), 0, 0, 1), null_preds = null_preds + DECODE (BITAND (:flag, 32), 0, 0, 1), TIMESTAMP = :TIME WHERE obj# = :objn AND intcol# = :coln; INSERT INTO SYS.col_usage$ VALUES (:objn, :coln, DECODE (BITAND (:flag, 1), 0, 0, 1), DECODE (BITAND (:flag, 2), 0, 0, 1), DECODE (BITAND (:flag, 4), 0, 0, 1), DECODE (BITAND (:flag, 8), 0, 0, 1), DECODE (BITAND (:flag, 16), 0, 0, 1), DECODE (BITAND (:flag, 32), 0, 0, 1), :TIME);
在如下1小時採樣的報告中,3條SQL執行了數千次:this
Parse Calls | Executions | % Total Parses | SQL Id | SQL Module | SQL Text |
---|---|---|---|---|---|
986 | 4,075 | 0.71 | 3c1kubcdjnppq | update sys.col_usage$ set eq... | |
986 | 69 | 0.71 | 53btfq0dt9bs9 | insert into sys.col_usage$ val... | |
986 | 986 | 0.71 | b2gnxm5z6r51n | lock table sys.col_usage$ in e... |
相關的維護SQL還有:設計
delete from sys.col_usage$ c where not exists (select 1 from sys.obj$ o where o.obj# = c.obj# )
若是想關閉這個特性,能夠經過設置_column_tracking_level = 0來實現。
如下這段SQL在進行CBO統計信息收集時,會被調用用於獲取列的使用信息,以肯定是否要進行基於COLUMN的柱狀圖信息收集等(Oracle9i版本):code
SELECT /*+ RULE */ c.NAME col_name, c.type# col_type, c.CHARSETFORM col_csf, c.default$ col_def, c.null$ col_null, c.property col_prop, c.col# col_unum, c.intcol# col_inum, c.obj# col_obj, c.scale col_scale, h.bucket_cnt h_bcnt, h.distcnt h_pndv, c.LENGTH col_len, cu.TIMESTAMP cu_time, cu.equality_preds cu_ep, cu.equijoin_preds cu_ejp, cu.range_preds cu_rp, cu.like_preds cu_lp FROM SYS.user$ u, SYS.obj$ o, SYS.col$ c, SYS.col_usage$ cu, SYS.hist_head$ h WHERE u.NAME = :b1 AND o.owner# = u.user# AND o.type# = 2 AND o.NAME = :b2 AND o.obj# = c.obj# AND c.obj# = cu.obj#(+) AND c.intcol# = cu.intcol#(+) AND c.obj# = h.obj#(+) AND c.intcol# = h.intcol#(+);