11gR2游标共享新特性带来的一些问题以及_cursor_features_enabled、_cursor_obsolete_threshold和106001 event

版本11gR2中引入cursor sharing游标共享和mutex互斥锁增强的一些特性,而这些特性也带来了一些问题(主要体现在版本11.2.0.1和11.2.0.2上,11.2.0.3上基本已经修复)。

Cursor Obsolescence游标废弃是一种SQL Cursor游标管理方面的增强特性,该特性启用后若parent cursor父游标名下的子游标child cursor总数超过一定的数目,则该父游标parent cursor将被废弃,同时一个新的父游标将被开始。 这样做有2点好处:

  • 避免进程去扫描长长的子游标列表child cursor list以找到一个合适的子游标child cursor
  • 废弃的游标将在一定时间内被age out,其占用的内存可以被重新利用

 

实际在版本10g中就引入了该Cursor Obsolescence游标废弃特性,当时child cursor 的总数阀值是1024, 但是这个阀值在11g中被移除了,这导致出现一个父游标下大量child cursor即high version count的发生;由此引发了一系列的版本11.2.0.3之前的cursor sharing 性能问题,主要症状是版本11.2.0.1和11.2.0.2上出现大量的Cursor: Mutex S 和 library cache lock等待事件。

增强补丁Enhancement patch《Bug 10187168 – Enhancement to obsolete parent cursors if VERSION_COUNT exceeds a threshold》就该问题引入了新的隐藏参数_cursor_obsolete_threshold(Number of cursors per parent before obsoletion.),该”_cursor_obsolete_threshold”参数用以指定子游标总数阀值,若一个父游标的child cursor count<=>version count高于”_cursor_obsolete_threshold”,则触发Cursor Obsolescence游标废弃特性。

 

注意版本11.2.0.3中默认就有”_cursor_obsolete_threshold”了,而且默认值为100。

 

对于版本11.1.0.7、11.2.0.1和11.2.0.2则都有该Bug 10187168的bug backport存在,从2011年5月开始就有相关针对的one-off backport补丁存在。 但是这些one-off backport补丁不使用”_cursor_obsolete_threshold”参数。在版本11.1.0.7、11.2.0.1和11.2.0.2上需要设置合适的”_cursor_features_enabled”(默认值为2)参数,并设置必要的106001 event,该event的level值即是child cursor count的阀值,必须设置该106001事件后该特性才生效。

但是请注意 “_cursor_features_enabled”参数需要重启实例方能生效。而”_cursor_obsolete_threshold”参数和106001 event则可以在线启用、禁用。

对于不同的版本而言,一般推荐打上最新的PSU补丁,并根据补丁的README提示或者咨询Oracle Support获得关于该版本上Cursor Obsolescence问题的信息:
针对不同版本设置 “_cursor_features_enabled”+106001 event的方法:

 

版本11.1.0.7

SQL> alter system set "_cursor_features_enabled"=18 scope=spfile;

System altered.

SQL> alter system set event='106001 trace name context forever,level 1024' scope=spfile;

System altered.

并重启实例

版本11.2.0.1

SQL> alter system set "_cursor_features_enabled"=34 scope=spfile;

System altered.

SQL> alter system set event='106001 trace name context forever,level 1024' scope=spfile;

System altered.

版本11.2.0.2

SQL> alter system set "_cursor_features_enabled"=1026 scope=spfile;

System altered.

SQL> alter system set event='106001 trace name context forever,level 1024' scope=spfile;

System altered.

11gR2 Experience -> If using cursor_sharing = “FORCE” or “SIMILAR”
1) ORA-600 errors as workload increases [kkspsc0: basehd]
or [kglLockOwnersListAppend-ovf] - applied patches to address
2) AWR showing -> cursor: mutex S and library cache lock
1. Download and apply the 11.2.0.2.3PSU Patch 11724916
2. Enable event 106001 to address Bug 10187168.
To enable the fix "_cursor_features_enabled" needs to be set
3) Oracle 11.2.0.2.2 PSU (Patch Set Update) includes new parameters that you can tweak
based on workload characteristics. Even more fixes have been added
Note: 10411618 - Enhancement to add different "Mutex" wait schemes [ID 10411618.8]
4) 11.2.0.3 Has many Mutex enhancement’s

106001 level
The level is used to specify the maximum number of child cursors 
that a parent can have before we obsolete
the parent cursor and create a new parent.
Doing the above can help reduce mutex waits, 
memory consumption and other side effects seen when we see
many child cursors for a given parent.

 

 

 

题外话是11.2.0.3中的Mutex增强了很多,不要再跟着初学者论坛的那帮家伙一起愚蠢地大喊:”虽然版本升级 8i=>9i=>10g=>11g=>12c,但是我觉得oracle里面基础、核心的东西一直都没变了”这种神话了, 你一直浮游在Oracle的表面怎么可能知道Kernel到底有多大的变化?!!

详解dbms_stats.gather_fixed_objects_stats

exec dbms_stats.gather_fixed_objects_stats;

 

该gather_fixed_objects_stats存储过程收集的X$基表对象如下,一般建议在系统高峰时段收集 例如大量session登陆之后,以保证v$SESSION、V$PROCESS、V$LOCK等常用视图相关的SQL语句执行计划恰当。

select table_name,num_rows,last_analyzed from dba_tab_statistics where last_analyzed is not null order by last_analyzed desc

 

Table_name Num_rows Last_analyzed
X$XS_SESSION_NS_ATTRIBUTES 0 2013/8/16 9:34
X$XS_SESSION_ROLES 0 2013/8/16 9:34
X$XS_SESSIONS 0 2013/8/16 9:34
X$ZASAXTAB 0 2013/8/16 9:34
X$XSOQOPLU 0 2013/8/16 9:34
X$XSOQSEHI 0 2013/8/16 9:34
X$XSOQOJHI 0 2013/8/16 9:34
X$XSOQOPHI 0 2013/8/16 9:34
X$XSSINFO 0 2013/8/16 9:34
X$XPLTON 141 2013/8/16 9:34
X$XPLTOO 188 2013/8/16 9:34
X$XML_AUDIT_TRAIL 0 2013/8/16 9:34
X$VINST 0 2013/8/16 9:34
X$XSAWSO 16 2013/8/16 9:34
X$XSAGOP 29 2013/8/16 9:34
X$XSOBJECT 0 2013/8/16 9:34
X$XSLONGOPS 0 2013/8/16 9:34
X$XSOQMEHI 0 2013/8/16 9:34
X$XSAGGR 0 2013/8/16 9:34
X$SKGXPIA 0 2013/8/16 9:34
X$TRACE 5810 2013/8/16 9:34
X$TRACE_EVENTS 1000 2013/8/16 9:34
X$TIMEZONE_NAMES 2226 2013/8/16 9:34
X$TIMEZONE_FILE 1 2013/8/16 9:34
X$VERSION 5 2013/8/16 9:34
X$UNFLUSHED_DEQUEUES 0 2013/8/16 9:34
X$RXS_SESSION_ROLES 0 2013/8/16 9:34
X$UNIFIED_AUDIT_RECORD_FORMAT 93 2013/8/16 9:34
X$TEMPORARY_LOB_REFCNT 8 2013/8/16 9:34
X$UGANCO 0 2013/8/16 9:34
X$RULE_SET 1 2013/8/16 9:34
X$TARGETRBA 1 2013/8/16 9:34
X$QUIESCE 1 2013/8/16 9:34
X$QKSMMWDS 1209 2013/8/16 9:34
X$QKSHT 314 2013/8/16 9:34
X$QKSXA_REASON 353 2013/8/16 9:34
X$RULE 1 2013/8/16 9:34
X$RFMP 1 2013/8/16 9:34
X$RFMTE 0 2013/8/16 9:34
X$RFAHIST 0 2013/8/16 9:34
X$RFAFO 0 2013/8/16 9:34
X$RO_USER_ACCOUNT 0 2013/8/16 9:34
X$QKSCESYS 415 2013/8/16 9:34
X$QKSCESES 21165 2013/8/16 9:34
X$QKSBGSYS 884 2013/8/16 9:34
X$QKSBGSES 45084 2013/8/16 9:34
X$QKSCR_RSN 0 2013/8/16 9:34
X$QKSFMPRT 1001 2013/8/16 9:34
X$QKSFMDEP 996 2013/8/16 9:34
X$QKSCR 0 2013/8/16 9:34
X$QKSFM 996 2013/8/16 9:34
X$PROPS 38 2013/8/16 9:34
X$POLICY_HISTORY 0 2013/8/16 9:34
X$OPTIM_CALIB_STATS 25 2013/8/16 9:34
X$ORAFN 188 2013/8/16 9:34
X$PRMSLTYX 26 2013/8/16 9:34
X$PERSISTENT_PUBLISHERS 0 2013/8/16 9:34
X$OPVERSION 1008 2013/8/16 9:34
X$QERFXTST 10 2013/8/16 9:34
X$PERSISTENT_QUEUES 0 2013/8/16 9:34
X$PERSISTENT_SUBSCRIBERS 0 2013/8/16 9:34
X$OPTION 82 2013/8/16 9:34
X$OFS_STATS 0 2013/8/16 9:34
X$OFS_RW_LATENCY_STATS 0 2013/8/16 9:34
X$OBJECT_POLICY_STATISTICS 0 2013/8/16 9:34
X$OFSMOUNT 0 2013/8/16 9:34
X$OPARG 589 2013/8/16 9:34
X$NSV 0 2013/8/16 9:34
X$OPERATORS 1008 2013/8/16 9:34
X$OPDESC 1008 2013/8/16 9:34
X$OCT 242 2013/8/16 9:34
X$MESSAGES 416 2013/8/16 9:34
X$NLS_PARAMETERS 20 2013/8/16 9:34
X$MODACT_LENGTH 1 2013/8/16 9:34
X$MUTEX_SLEEP_HISTORY 77 2013/8/16 9:34
X$MUTEX_SLEEP 14 2013/8/16 9:34
X$MSGBM 0 2013/8/16 9:34
X$NONDURSUB 0 2013/8/16 9:34
X$NONDURSUB_LWM 0 2013/8/16 9:34
X$NFSCLIENTS 0 2013/8/16 9:34
X$NFSOPENS 0 2013/8/16 9:34
X$NFSLOCKS 0 2013/8/16 9:34
X$MESSAGE_CACHE 0 2013/8/16 9:34
X$LOGMNR_TAB$ 0 2013/8/16 9:34
X$LOGMNR_TS$ 0 2013/8/16 9:34
X$LOGMNR_USER$ 0 2013/8/16 9:34
X$LOGMNR_TABPART$ 0 2013/8/16 9:34
X$LOGMNR_TABSUBPART$ 0 2013/8/16 9:34
X$LOGMNR_SESSION 0 2013/8/16 9:34
X$LOGMNR_TYPE$ 0 2013/8/16 9:34
X$LOGMNR_UET$ 0 2013/8/16 9:34
X$LOGMNR_UNDO$ 0 2013/8/16 9:34
X$LOGMNR_SUBCOLTYPE$ 0 2013/8/16 9:34
X$LOGMNR_TABCOMPART$ 0 2013/8/16 9:34
X$LOGMNR_LOGS 0 2013/8/16 9:34
X$LOGMNR_PARAMETERS 0 2013/8/16 9:34
X$LOGMNR_ROOT$ 0 2013/8/16 9:34
X$LOGMNR_OBJ$ 0 2013/8/16 9:34
X$LOGMNR_SEG$ 0 2013/8/16 9:34
X$LOGMNR_PROCESS 0 2013/8/16 9:34
X$LOGMNR_OPQTYPE$ 0 2013/8/16 9:34
X$LOGMNR_PARTOBJ$ 0 2013/8/16 9:34
X$LOGMNR_PROPS$ 0 2013/8/16 9:34
X$LOGMNR_REFCON$ 0 2013/8/16 9:34
X$LOGMNR_NTAB$ 0 2013/8/16 9:34
X$LOGMNR_INDPART$ 0 2013/8/16 9:34
X$LOGMNR_INDSUBPART$ 0 2013/8/16 9:34
X$LOGMNR_LOB$ 0 2013/8/16 9:34
X$LOGMNR_LOBFRAG$ 0 2013/8/16 9:34
X$LOGMNR_LOG 0 2013/8/16 9:34
X$LOGMNR_KOPM$ 0 2013/8/16 9:34
X$LOGMNR_LATCH 0 2013/8/16 9:34
X$LOGMNR_LOGFILE 0 2013/8/16 9:34
X$LOGMNR_KTFBUE 0 2013/8/16 9:34
X$LOGMNR_DICTIONARY 0 2013/8/16 9:34
X$LOGMNR_COL$ 0 2013/8/16 9:34
X$LOGMNR_IND$ 0 2013/8/16 9:34
X$LOGMNR_COLTYPE$ 0 2013/8/16 9:34
X$LOGMNR_ENCRYPTION_PROFILE$ 0 2013/8/16 9:34
X$LOGMNR_DICTIONARY_LOAD 0 2013/8/16 9:34
X$LOGMNR_ENC$ 0 2013/8/16 9:34
X$LOGMNR_CLU$ 0 2013/8/16 9:34
X$LOGMNR_FILE$ 0 2013/8/16 9:34
X$LOGMNR_INDCOMPART$ 0 2013/8/16 9:34
X$LOGMNR_ENCRYPTED_OBJ$ 0 2013/8/16 9:34
X$LOBSTATHIST 18 2013/8/16 9:34
X$LOBSTAT 3 2013/8/16 9:34
X$LOBSEGSTAT 0 2013/8/16 9:34
X$LOGMNR_ATTRIBUTE$ 0 2013/8/16 9:34
X$LE 0 2013/8/16 9:34
X$LOGMNR_CDEF$ 0 2013/8/16 9:34
X$LOGMNR_CALLBACK 0 2013/8/16 9:34
X$LOGBUF_READHIST 16 2013/8/16 9:34
X$LOGMNR_ATTRCOL$ 0 2013/8/16 9:34
X$KZDOS 0 2013/8/16 9:34
X$KZSRO 2 2013/8/16 9:34
X$KZSPR 393 2013/8/16 9:34
X$KZSRT 6 2013/8/16 9:34
X$KZRTPD 0 2013/8/16 9:34
X$KZEKMENCWAL 1 2013/8/16 9:34
X$KZDPSUPSF 3 2013/8/16 9:34
X$KZCKMCS 0 2013/8/16 9:34
X$KZPOPR 99 2013/8/16 9:34
X$KZAJOBS 0 2013/8/16 9:34
X$KZAPARAMS 0 2013/8/16 9:34
X$KZATS 0 2013/8/16 9:34
X$KZCKMEK 0 2013/8/16 9:34
X$KYWMPCTAB 0 2013/8/16 9:34
X$KXSREPLAYLOB 0 2013/8/16 9:34
X$KYWMCLTAB 0 2013/8/16 9:34
X$KYWMNF 0 2013/8/16 9:34
X$KYWMPCMN 0 2013/8/16 9:34
X$KZAHIST 0 2013/8/16 9:34
X$KXTTSTETS 0 2013/8/16 9:34
X$KXTTSTECS 0 2013/8/16 9:34
X$KXTTSTEHS 0 2013/8/16 9:34
X$KXTTSTEIS 0 2013/8/16 9:34
X$KXSREPLAYTIME 0 2013/8/16 9:34
X$KXSREPLAYDATE 0 2013/8/16 9:34
X$KXSREPLAYGUID 0 2013/8/16 9:34
X$KXSREPLAYSEQ 0 2013/8/16 9:34
X$KYWMWRCTAB 0 2013/8/16 9:34
X$KXFSOURCE 0 2013/8/16 9:34
X$KXFTASK 0 2013/8/16 9:34
X$KXSREPLAY 0 2013/8/16 9:34
X$KXSBD 64 2013/8/16 9:34
X$KXSCC 64 2013/8/16 9:34
X$KXFPSMS 70 2013/8/16 9:34
X$KXFPYS 20 2013/8/16 9:34
X$KXFPSST 13 2013/8/16 9:34
X$KXFRSVCHASH 0 2013/8/16 9:34
X$KXFQSROW 0 2013/8/16 9:34
X$KXFPCST 26 2013/8/16 9:34
X$KXFPCMS 70 2013/8/16 9:34
X$KXFPNS 20 2013/8/16 9:34
X$KXFPPIG 0 2013/8/16 9:34
X$KXFPIG 0 2013/8/16 9:34
X$KXFPINSTLOAD 1 2013/8/16 9:34
X$KXFPDP 16 2013/8/16 9:34
X$KXFPPFT 100 2013/8/16 9:34
X$KXFPBS 5 2013/8/16 9:34
X$KXDRS 0 2013/8/16 9:34
X$KXFPCDS 47 2013/8/16 9:34
X$KXFPSDS 47 2013/8/16 9:34
X$KXFPREMINSTLOAD 0 2013/8/16 9:34
X$KXDBIO_STATS 0 2013/8/16 9:34
X$KWSCPJOBSTAT 0 2013/8/16 9:34
X$KWSBGAQPCSTAT 1 2013/8/16 9:34
X$KWSBGQMNSTAT 1 2013/8/16 9:34
X$KWQMNTASKSTAT 23 2013/8/16 9:34
X$KWSBJCSQJIT 0 2013/8/16 9:34
X$KWQPS 0 2013/8/16 9:34
X$KWQPD 0 2013/8/16 9:34
X$KWRSNV 13 2013/8/16 9:34
X$KWSBSMSLVSTAT 2 2013/8/16 9:34
X$KVII 12 2013/8/16 9:34
X$KVIS 0 2013/8/16 9:34
X$KVIT 18 2013/8/16 9:34
X$KUPVJ 0 2013/8/16 9:34
X$KWDDEF 2089 2013/8/16 9:34
X$KWQDLSTAT 32 2013/8/16 9:34
X$KWQBPMT 1 2013/8/16 9:34
X$KWQMNC 1 2013/8/16 9:34
X$KWQMNSCTX 2 2013/8/16 9:34
X$KWQMNTASK 2 2013/8/16 9:34
X$KWQMNJIT 12 2013/8/16 9:34
X$KWQITCX 1 2013/8/16 9:34
X$KTUGD 1 2013/8/16 9:33
X$KTUXE 438 2013/8/16 9:33
X$KTUSMST 7 2013/8/16 9:33
X$KTUSMST2 3 2013/8/16 9:33
X$KTUSUS 10 2013/8/16 9:33
X$KTTETS 11 2013/8/16 9:33
X$KTUTST 0 2013/8/16 9:33
X$KTURHIST 0 2013/8/16 9:33
X$KTUMASCN 1 2013/8/16 9:33
X$KUPVA 0 2013/8/16 9:33
X$KTTVS 11 2013/8/16 9:33
X$KTUCUS 0 2013/8/16 9:33
X$KTSTSSD 1 2013/8/16 9:33
X$KTSSO 1 2013/8/16 9:33
X$KTSTFC 0 2013/8/16 9:33
X$KTSTUSC 8 2013/8/16 9:33
X$KTSLCHUNK 0 2013/8/16 9:33
X$KTSTUSG 8 2013/8/16 9:33
X$KTSPSTAT 1 2013/8/16 9:33
X$KTTEFINFO 11 2013/8/16 9:33
X$KTSSPU 0 2013/8/16 9:33
X$KTSTUSS 8 2013/8/16 9:33
X$KTFTHC 1 2013/8/16 9:33
X$KTFTME 0 2013/8/16 9:33
X$KTPRXRS 0 2013/8/16 9:33
X$KTPRXRT 0 2013/8/16 9:33
X$KTPRHIST 0 2013/8/16 9:33
X$KTSKSTAT 0 2013/8/16 9:33
X$KTIFP 51 2013/8/16 9:33
X$KTIFF 21 2013/8/16 9:33
X$KTIFB 16 2013/8/16 9:33
X$KTIFV 0 2013/8/16 9:33
X$KTRSO 0 2013/8/16 9:33
X$KTCNREGQUERY 0 2013/8/16 9:33
X$KTFBNSTAT 0 2013/8/16 9:33
X$KTFBHC 10 2013/8/16 9:33
X$KTFSTAT 0 2013/8/16 9:33
X$KTFSIMSTAT 0 2013/8/16 9:33
X$KTFSAN 1 2013/8/16 9:33
X$KTFSBI 0 2013/8/16 9:33
X$KTFSRI 0 2013/8/16 9:33
X$KTCXB 517 2013/8/16 9:33
X$KTCSP 0 2013/8/16 9:33
X$KTCNREG 0 2013/8/16 9:33
X$KTFTBTXNMODS 0 2013/8/16 9:33
X$KTFTBTXNGRAPH 0 2013/8/16 9:33
X$KTCNQUERY 0 2013/8/16 9:33
X$KTCNQROW 0 2013/8/16 9:33
X$KTFBFE 32 2013/8/16 9:33
X$KSXRMSG 0 2013/8/16 9:33
X$KSXRREPQ 0 2013/8/16 9:33
X$KSXRCONQ 0 2013/8/16 9:33
X$KSXRSG 1 2013/8/16 9:33
X$KTATL 8 2013/8/16 9:33
X$KTCNINBAND 0 2013/8/16 9:33
X$KTADM 2112 2013/8/16 9:33
X$KTATRFIL 8 2013/8/16 9:33
X$KTATRFSL 8 2013/8/16 9:33
X$KTCNCLAUSES 0 2013/8/16 9:33
X$KSXPPING 0 2013/8/16 9:33
X$KSXPCLIENT 0 2013/8/16 9:33
X$KSXPIF 0 2013/8/16 9:33
X$KSXPIA 0 2013/8/16 9:33
X$KSXAFA 11 2013/8/16 9:33
X$KSWSEVTAB 1792 2013/8/16 9:33
X$KSWSCRSTAB 0 2013/8/16 9:33
X$KSXM_DFT 0 2013/8/16 9:33
X$KSXRCH 0 2013/8/16 9:33
X$KSWSCRSSVCTAB 0 2013/8/16 9:33
X$KSWSASTAB 4 2013/8/16 9:33
X$KSWSCLSTAB 52 2013/8/16 9:33
X$KSUSEX 472 2013/8/16 9:33
X$KSUSGSTA 839 2013/8/16 9:33
X$KSUTM 1 2013/8/16 9:33
X$KSUSGIF 1 2013/8/16 9:33
X$KSWSAFTAB 0 2013/8/16 9:33
X$KSUSIO 472 2013/8/16 9:33
X$KSUVMSTAT 2 2013/8/16 9:33
X$KSUSM 472 2013/8/16 9:33
X$KSUXSINST 1 2013/8/16 9:33
X$KSUSESTA 396008 2013/8/16 9:33
X$KSUSE 472 2013/8/16 9:33
X$KSUSECON 476 2013/8/16 9:33
X$KSUSECST 472 2013/8/16 9:33
X$KSUPR 300 2013/8/16 9:33
X$KSUPRLAT 0 2013/8/16 9:33
X$KSURLMT 27 2013/8/16 9:33
X$KSUPL 10 2013/8/16 9:33
X$KSUPGS 0 2013/8/16 9:33
X$KSURU 4720 2013/8/16 9:33
X$KSUSD 839 2013/8/16 9:33
X$KSUINSTSTAT 0 2013/8/16 9:33
X$KSUMYSTA 839 2013/8/16 9:33
X$KSULOP 8 2013/8/16 9:33
X$KSUPGP 53 2013/8/16 9:33
X$KSUCF 10 2013/8/16 9:33
X$KSUCLNDPCC 0 2013/8/16 9:33
X$KSUCPUSTAT 13 2013/8/16 9:33
X$KSUNETSTAT 0 2013/8/16 9:33
X$KSUPDBSES 254 2013/8/16 9:33
X$KSTEX 0 2013/8/16 9:33
X$KSULV 556 2013/8/16 9:33
X$KSULL 1 2013/8/16 9:33
X$KSQEQTYP 241 2013/8/16 9:33
X$KSQRS 2304 2013/8/16 9:33
X$KSQST 419 2013/8/16 9:33
X$KSRPCIOS 3 2013/8/16 9:33
X$KSRMSGO 0 2013/8/16 9:33
X$KSRCCTX 253 2013/8/16 9:33
X$KSRMSGDES 95 2013/8/16 9:33
X$KSRMPCTX 95 2013/8/16 9:33
X$KSRCHDL 94 2013/8/16 9:33
X$KSRCDES 253 2013/8/16 9:33
X$KSQDN 1 2013/8/16 9:33
X$KSPPI 3341 2013/8/16 9:33
X$KSPPSV 3341 2013/8/16 9:33
X$KSPPSV2 3346 2013/8/16 9:33
X$KSQEQ 5872 2013/8/16 9:33
X$KSPSPFH 1 2013/8/16 9:33
X$KSPVLD_VALUES 701 2013/8/16 9:33
X$KSPPO 133 2013/8/16 9:33
X$KSPSPFILE 3342 2013/8/16 9:33
X$KSMSTRS 4 2013/8/16 9:33
X$KSMUP 3323 2013/8/16 9:33
X$KSMSST 0 2013/8/16 9:33
X$KSMSSINFO 0 2013/8/16 9:33
X$KSOLTD 0 2013/8/16 9:33
X$KSPPCV2 3346 2013/8/16 9:33
X$KSOLSSTAT 22 2013/8/16 9:33
X$KSOLSFTS 24464 2013/8/16 9:33
X$KSO_SCHED_DELAY_HISTORY 902 2013/8/16 9:33
X$KSPPCV 3341 2013/8/16 9:33
X$KSMLRU 10 2013/8/16 9:33
X$KSMSPR 117 2013/8/16 9:33
X$KSMPP 437 2013/8/16 9:33
X$KSMSP_DSNEW 1 2013/8/16 9:33
X$KSMSP_NWEX 22 2013/8/16 9:33
X$KSMSGMEM 12 2013/8/16 9:33
X$KSMLS 5 2013/8/16 9:33
X$KSMPGDST 0 2013/8/16 9:33
X$KSMPGDP 0 2013/8/16 9:33
X$KSMSD 4 2013/8/16 9:33
X$KSMSS 1079 2013/8/16 9:33
X$KSMNS 0 2013/8/16 9:33
X$KSMNIM 0 2013/8/16 9:33
X$KSMPGST 1800 2013/8/16 9:33
X$KSLWSC 6581 2013/8/16 9:33
X$KSLWH 331 2013/8/16 9:33
X$KSLWT 35 2013/8/16 9:33
X$KSMFS 5 2013/8/16 9:33
X$KSMJS 4 2013/8/16 9:33
X$KSMGE 103 2013/8/16 9:33
X$KSMHP 0 2013/8/16 9:33
X$KSMJCH 0 2013/8/16 9:33
X$KSMDD 354 2013/8/16 9:33
X$KSMDUT1 320 2013/8/16 9:33
X$KSMFSV 16387 2013/8/16 9:33
X$KSLPO 458 2013/8/16 9:33
X$KSLLTR 703 2013/8/16 9:33
X$KSLHOT 10 2013/8/16 9:33
X$KSLLCLASS 8 2013/8/16 9:33
X$KSLLD 703 2013/8/16 9:33
X$KSLSCS 13 2013/8/16 9:33
X$KSLES 211456 2013/8/16 9:33
X$KSLSESHIST 943 2013/8/16 9:33
X$KSLLW 6581 2013/8/16 9:33
X$KSI_REUSE_STATS 415 2013/8/16 9:33
X$KSLECLASS 125 2013/8/16 9:33
X$KSLEMAP 1567 2013/8/16 9:33
X$KSLED 1567 2013/8/16 9:33
X$KSLEPX 9 2013/8/16 9:33
X$KSIRPINFO 0 2013/8/16 9:33
X$KSLEI 1567 2013/8/16 9:33
X$KSKPLW 1 2013/8/16 9:33
X$KSKQVFT 0 2013/8/16 9:33
X$KSKQDFT 0 2013/8/16 9:33
X$KSIRGD 0 2013/8/16 9:33
X$KSLCS 6136 2013/8/16 9:33
X$KSIRESTYP 241 2013/8/16 9:33
X$KSIMSI 0 2013/8/16 9:33
X$KSFQP 0 2013/8/16 9:33
X$KSFQDVNT 1 2013/8/16 9:33
X$KSFVQST 192 2013/8/16 9:33
X$KSFVSTA 32 2013/8/16 9:33
X$KSIMAT 5 2013/8/16 9:33
X$KSFMLIB 0 2013/8/16 9:33
X$KSFMIOST 0 2013/8/16 9:33
X$KSFMFILE 0 2013/8/16 9:33
X$KSFMFILEEXT 0 2013/8/16 9:33
X$KSFMSUBELEM 0 2013/8/16 9:33
X$KSIMAV 0 2013/8/16 9:33
X$KSFVSL 0 2013/8/16 9:33
X$KSFDSTCG 96 2013/8/16 9:33
X$KSFDSTCMP 1764 2013/8/16 9:33
X$KSFDSTFILE 53 2013/8/16 9:33
X$KSFDSTBLK 0 2013/8/16 9:33
X$KSFMCOMPL 0 2013/8/16 9:33
X$KSFDSTTHIST 1 2013/8/16 9:33
X$KSFDSTLL 65 2013/8/16 9:33
X$KSFMELEM 0 2013/8/16 9:33
X$KSFMEXTELEM 0 2013/8/16 9:33
X$KSFDSTHIST 13 2013/8/16 9:33
X$KSBDPNEEDED 1 2013/8/16 9:33
X$KSBFT 76 2013/8/16 9:33
X$KSBSRVDT 124 2013/8/16 9:33
X$KSBTABACT 3210 2013/8/16 9:33
X$KSFDFTYP 37 2013/8/16 9:33
X$KSFDSSCLONEINFO 0 2013/8/16 9:33
X$KSDAFT 0 2013/8/16 9:33
X$KSFDKLL 0 2013/8/16 9:33
X$KSDHNG_CHAINS 1 2013/8/16 9:33
X$KSDHNG_SESSION_BLOCKERS 0 2013/8/16 9:33
X$KSDHNG_CACHE_HISTORY 20 2013/8/16 9:33
X$KSDAF 0 2013/8/16 9:33
X$KSBDP 402 2013/8/16 9:33
X$KSBDD 402 2013/8/16 9:33
X$KSAST 300 2013/8/16 9:33
X$KRVXDTA 45 2013/8/16 9:33
X$KRVXTX 0 2013/8/16 9:33
X$KRVXISPLCR 0 2013/8/16 9:33
X$KRVXOP 0 2013/8/16 9:33
X$KRVXTHRD 0 2013/8/16 9:33
X$KRVXWARNV 0 2013/8/16 9:33
X$KRVXISPCHK 0 2013/8/16 9:33
X$KRVXSV 0 2013/8/16 9:33
X$KRVXDKA 32 2013/8/16 9:33
X$KRVSLV 0 2013/8/16 9:33
X$KRVSLVS 0 2013/8/16 9:33
X$KRVSLVPG 0 2013/8/16 9:33
X$KRVSLVST 0 2013/8/16 9:33
X$KRSTALG 13 2013/8/16 9:33
X$KRSTAPPSTATS 1055 2013/8/16 9:33
X$KRSTDGC 0 2013/8/16 9:33
X$KRSTDEST 31 2013/8/16 9:33
X$KRSTPVRS 0 2013/8/16 9:33
X$KRVSLVTHRD 0 2013/8/16 9:33
X$KRSSMS 4 2013/8/16 9:33
X$KRFSTHRD 0 2013/8/16 9:33
X$KRDRSBROV 0 2013/8/16 9:33
X$KRDEVTHIST 0 2013/8/16 9:33
X$KRDMMIRA 0 2013/8/16 9:33
X$KRCGFE 0 2013/8/16 9:33
X$KRCSTAT 1 2013/8/16 9:33
X$KRFBLOG 0 2013/8/16 9:33
X$KRFGSTAT 0 2013/8/16 9:33
X$KRCFH 0 2013/8/16 9:33
X$KRBPHEAD 0 2013/8/16 9:33
X$KRBPDIR 0 2013/8/16 9:33
X$KRCEXT 0 2013/8/16 9:33
X$KRCCDE 0 2013/8/16 9:33
X$KRBZA 3 2013/8/16 9:33
X$KRCCDR 0 2013/8/16 9:33
X$KRCFDE 0 2013/8/16 9:33
X$KRCFBH 0 2013/8/16 9:33
X$KRCBIT 0 2013/8/16 9:33
X$KRCCDS 0 2013/8/16 9:33
X$KRBPDATA 0 2013/8/16 9:33
X$KRBAFF 10 2013/8/16 9:33
X$KRBMSFT 0 2013/8/16 9:33
X$KRBMRST 0 2013/8/16 9:33
X$KRASGA 1 2013/8/16 9:33
X$KRBMCA 6 2013/8/16 9:33
X$KQRST 69 2013/8/16 9:33
X$KQRPD 59 2013/8/16 9:33
X$KQRSD 14 2013/8/16 9:33
X$KRBMROT 0 2013/8/16 9:33
X$KQFTA 1107 2013/8/16 9:33
X$KQFVI 1261 2013/8/16 9:33
X$KQFVT 1261 2013/8/16 9:33
X$KQFDT 37 2013/8/16 9:33
X$KQFCO 18145 2013/8/16 9:33
X$KQFTVRTTST0 1 2013/8/16 9:33
X$KQRFP 7719 2013/8/16 9:33
X$KQRFS 1948 2013/8/16 9:33
X$KQFSZ 45 2013/8/16 9:33
X$KQFP 37 2013/8/16 9:33
X$KQFOPT 129 2013/8/16 9:33
X$KQDPG 1 2013/8/16 9:33
X$KPOQSTA 0 2013/8/16 9:33
X$KPONESTAT 0 2013/8/16 9:33
X$KPONJSTAT 1 2013/8/16 9:33
X$KPPLCONN_INFO 0 2013/8/16 9:33
X$KPONDESTAT 0 2013/8/16 9:33
X$KPPLCC_INFO 0 2013/8/16 9:33
X$KPPLCC_STATS 0 2013/8/16 9:33
X$KPPLCP_STATS 0 2013/8/16 9:33
X$KPONDCONSTAT 0 2013/8/16 9:33
X$KNSTMVR 0 2013/8/16 9:33
X$KNSTCAPS 0 2013/8/16 9:33
X$KNSTRQU 1 2013/8/16 9:33
X$KNSTTXN 0 2013/8/16 9:33
X$KNSTRPP 0 2013/8/16 9:33
X$KNSTXSTS 0 2013/8/16 9:33
X$KNSTOGGC 4 2013/8/16 9:33
X$KNSTSESS 3 2013/8/16 9:33
X$KOCST 1 2013/8/16 9:33
X$KNSTMT 0 2013/8/16 9:33
X$KNSTCAP 0 2013/8/16 9:33
X$KNSTCAPCACHE 0 2013/8/16 9:33
X$KNSTANR 0 2013/8/16 9:33
X$KNSTASL 0 2013/8/16 9:33
X$KNSTACR 0 2013/8/16 9:33
X$KNGFL 0 2013/8/16 9:33
X$KNGFLE 0 2013/8/16 9:33
X$KNLAROW 0 2013/8/16 9:33
X$KNLASG 1 2013/8/16 9:33
X$KMPSRV 8 2013/8/16 9:33
X$KMPCP 4 2013/8/16 9:33
X$KMPCSO 1 2013/8/16 9:33
X$KMPDH 4 2013/8/16 9:33
X$KMPCMON 4 2013/8/16 9:33
X$KMMSI 16 2013/8/16 9:33
X$KMGSTFR 800 2013/8/16 9:33
X$KMGSOP 22 2013/8/16 9:33
X$KMMDI 2 2013/8/16 9:33
X$KMMSG 1 2013/8/16 9:33
X$KMMNV 2 2013/8/16 9:33
X$KMMRD 192 2013/8/16 9:33
X$KMMSAS 1 2013/8/16 9:33
X$KMMHST 1 2013/8/16 9:33
X$KMMDP 1 2013/8/16 9:33
X$KMGSCT 17 2013/8/16 9:33
X$KMGSBSADV 7 2013/8/16 9:33
X$KMGSBSMEMADV 0 2013/8/16 9:33
X$KKOCS_HISTOGRAM 150 2013/8/16 9:33
X$KMCVC 0 2013/8/16 9:33
X$KKOCS_STATISTICS 0 2013/8/16 9:33
X$KLPT 0 2013/8/16 9:33
X$KLCIE 0 2013/8/16 9:33
X$KMCQS 6 2013/8/16 9:33
X$KKOCS_SELECTIVITY 0 2013/8/16 9:33
X$KJZSIWTEVT 0 2013/8/16 9:33
X$KJZNHANGSES 0 2013/8/16 9:33
X$KJZNWLMPCRANK 0 2013/8/16 9:33
X$KJZNRSLNRC 0 2013/8/16 9:33
X$KJZNHNGSTATS 0 2013/8/16 9:33
X$KKOAR_HINT 17 2013/8/16 9:33
X$KKKICR 1 2013/8/16 9:33
X$KKAEET 11 2013/8/16 9:33
X$KKCNRSTAT 0 2013/8/16 9:33
X$KKCNEREG 0 2013/8/16 9:33
X$KKCNEREGSTAT 0 2013/8/16 9:33
X$KJZNHNGMGRSTS 0 2013/8/16 9:33
X$KJR_FREEABLE_CHUNKS 0 2013/8/16 9:33
X$KJXM 0 2013/8/16 9:33
X$KJMSDP 0 2013/8/16 9:33
X$KJMDDP 0 2013/8/16 9:33
X$KJR_CHUNK_STATS 0 2013/8/16 9:33
X$KJZNHANGS 0 2013/8/16 9:33
X$KJZNCBHANGS 0 2013/8/16 9:33
X$KJREQFP 0 2013/8/16 9:33
X$KJRTBCFP 0 2013/8/16 9:33
X$KJPNPX 0 2013/8/16 9:33
X$KJLEQFP 0 2013/8/16 9:33
X$KJISFT 0 2013/8/16 9:33
X$KJILFT 0 2013/8/16 9:33
X$KJKMKGA 0 2013/8/16 9:33
X$KJIRFT 0 2013/8/16 9:33
X$KJITRFT 0 2013/8/16 9:33
X$KJIDT 1 2013/8/16 9:33
X$KJILKFT 0 2013/8/16 9:33
X$KJICVT 0 2013/8/16 9:32
X$KJFMHBACL 0 2013/8/16 9:32
X$KJDRPCMPF 0 2013/8/16 9:32
X$KJDDDEADLOCKS 0 2013/8/16 9:32
X$KJDDDEADLOCKSES 0 2013/8/16 9:32
X$KJCTFS 0 2013/8/16 9:32
X$KJCTFR 0 2013/8/16 9:32
X$KJCTFRI 0 2013/8/16 9:32
X$KJDRMREQ 0 2013/8/16 9:32
X$KJDRPCMHV 0 2013/8/16 9:32
X$KJDRMAFNSTATS 1 2013/8/16 9:32
X$KJDRMREADMOSTLYSTATS 1 2013/8/16 9:32
X$KJDRMHVSTATS 1 2013/8/16 9:32
X$KJDRHV 0 2013/8/16 9:32
X$KGSKVFT 34 2013/8/16 9:32
X$KJCISOT 7 2013/8/16 9:32
X$KJCISPT 2 2013/8/16 9:32
X$KJBR 0 2013/8/16 9:32
X$KJAC_CONFIG 1 2013/8/16 9:32
X$KJBL 0 2013/8/16 9:32
X$KJBLFX 0 2013/8/16 9:32
X$KJAC_ID 0 2013/8/16 9:32
X$KJAC_MY_ID 0 2013/8/16 9:32
X$KJBRFX 0 2013/8/16 9:32
X$KGSKTE 0 2013/8/16 9:32
X$KGSKTO 0 2013/8/16 9:32
X$KGSKCP 2 2013/8/16 9:32
X$KGSKPP 2 2013/8/16 9:32
X$KGSKASP 1 2013/8/16 9:32
X$KGSKSCS 0 2013/8/16 9:32
X$KGSKQUEP 1 2013/8/16 9:32
X$KGSKCFT 2 2013/8/16 9:32
X$KGSKNCFT 2 2013/8/16 9:32
X$KGSKPFT 1 2013/8/16 9:32
X$KGSKDOPP 1 2013/8/16 9:32
X$KGHLU 1 2013/8/16 9:32
X$KGSCC 1 2013/8/16 9:32
X$KGICS 1 2013/8/16 9:32
X$KFVOL 0 2013/8/16 9:32
X$KFVOLSTAT 0 2013/8/16 9:32
X$KFVACFSV 0 2013/8/16 9:32
X$KFZPBLK 0 2013/8/16 9:32
X$KFVACFSTAG 0 2013/8/16 9:32
X$KFVACFSRULESET 0 2013/8/16 9:32
X$KFVACFSRULESETRULE 0 2013/8/16 9:32
X$KFZUDR 0 2013/8/16 9:32
X$KFZGDR 0 2013/8/16 9:32
X$KFZUAGR 0 2013/8/16 9:32
X$KFVACFSS 0 2013/8/16 9:32
X$KFTMTA 0 2013/8/16 9:32
X$KFVACFS 0 2013/8/16 9:32
X$KFVACFSREALM 0 2013/8/16 9:32
X$KFVACFSENCR 0 2013/8/16 9:32
X$KFVACFSRULE 0 2013/8/16 9:32
X$KFVACFSREALMS 0 2013/8/16 9:32
X$KFVACFSREPLTAG 0 2013/8/16 9:32
X$KFVACFSREALMGROUP 0 2013/8/16 9:32
X$KFVACFSREALMFILTER 0 2013/8/16 9:32
X$KFVACFSCMDRULE 0 2013/8/16 9:32
X$KFVACFSADMIN 0 2013/8/16 9:32
X$KFVACFSREPL 0 2013/8/16 9:32
X$KFVACFSREALMUSER 0 2013/8/16 9:32
X$KFRC 0 2013/8/16 9:32
X$KFNSDSKIOST 0 2013/8/16 9:32
X$KFKID 0 2013/8/16 9:32
X$KFKLIB 0 2013/8/16 9:32
X$KFNRCL 0 2013/8/16 9:32
X$KFMDGRP 0 2013/8/16 9:32
X$KFNCL 0 2013/8/16 9:32
X$KFKLSOD 0 2013/8/16 9:32
X$KFGRP_STAT 0 2013/8/16 9:32
X$KFGXP 0 2013/8/16 9:32
X$KFIAS_FILE 0 2013/8/16 9:32
X$KFIAS_PROC 0 2013/8/16 9:32
X$KFIAS_CLNT 0 2013/8/16 9:32
X$KFGRP 0 2013/8/16 9:32
X$KFGMG 0 2013/8/16 9:32
X$KFGBRB 0 2013/8/16 9:32
X$KFGBRW 0 2013/8/16 9:32
X$KFFOF 0 2013/8/16 9:32
X$KFGBRC 0 2013/8/16 9:32
X$KFFXP 0 2013/8/16 9:32
X$KFGBRS 0 2013/8/16 9:32
X$KFFIL 0 2013/8/16 9:32
X$KFENV 0 2013/8/16 9:32
X$KFDSK_STAT 0 2013/8/16 9:32
X$KFDSR 0 2013/8/16 9:32
X$KFDXEXT 0 2013/8/16 9:32
X$KFDSK 0 2013/8/16 9:32
X$KFDFS 0 2013/8/16 9:32
X$KFDSD 0 2013/8/16 9:32
X$KFDPARTNER 0 2013/8/16 9:32
X$KFDDD 0 2013/8/16 9:32
X$KFCBH 0 2013/8/16 9:32
X$KFCCE 0 2013/8/16 9:32
X$KFBH 0 2013/8/16 9:32
X$KFCLLE 0 2013/8/16 9:32
X$KFDAT 0 2013/8/16 9:32
X$KFDAP 0 2013/8/16 9:32
X$KFCSTAT 0 2013/8/16 9:32
X$KFALS 0 2013/8/16 9:32
X$KEWSSVCV 112 2013/8/16 9:32
X$KEWRTB 125 2013/8/16 9:32
X$KEWX_SEGMENTS 0 2013/8/16 9:32
X$KEWX_LOBS 0 2013/8/16 9:32
X$KEWMWPCMV 0 2013/8/16 9:32
X$KEWRATTRSTALE 0 2013/8/16 9:32
X$KEWSSMAP 269 2013/8/16 9:32
X$KEWSSYSV 34 2013/8/16 9:32
X$KEWSSESV 38704 2013/8/16 9:32
X$KEWRSQLCRIT 0 2013/8/16 9:32
X$KEWMRWMV 28761 2013/8/16 9:32
X$KEWMSEMV 70 2013/8/16 9:32
X$KEWMFLMV 30 2013/8/16 9:32
X$KEWMIOFMV 420 2013/8/16 9:32
X$KEWMSMDV 161 2013/8/16 9:32
X$KEWMWCRMV 0 2013/8/16 9:32
X$KEWMRSM 219 2013/8/16 9:32
X$KEWMGSM 14 2013/8/16 9:32
X$KEWMRMGMV 0 2013/8/16 9:32
X$KEWMDRMV 31148 2013/8/16 9:32
X$KEWEFXT 0 2013/8/16 9:32
X$KEWESMS 0 2013/8/16 9:32
X$KEWMAFMV 0 2013/8/16 9:32
X$KEWEPCS 0 2013/8/16 9:32
X$KEWMEVMV 3524 2013/8/16 9:32
X$KEWMDSM 283 2013/8/16 9:32
X$KEWESMAS 0 2013/8/16 9:32
X$KEWECLS 0 2013/8/16 9:32
X$KEWASH 325 2013/8/16 9:32
X$KEWAM 1 2013/8/16 9:32
X$KESWXMON_STATNAME 75 2013/8/16 9:32
X$KETOP 15 2013/8/16 9:32
X$KETCL 7 2013/8/16 9:32
X$KESWXMON_PLAN 2 2013/8/16 9:32
X$KETTG 15 2013/8/16 9:32
X$KELTSD 175 2013/8/16 9:32
X$KESSPAMET 9 2013/8/16 9:32
X$KESPLAN 0 2013/8/16 9:32
X$KERPISTATS 1 2013/8/16 9:32
X$KEOMNMON_SESSTAT 0 2013/8/16 9:32
X$KERPIREPREQ 0 2013/8/16 9:32
X$KESWXMON 5 2013/8/16 9:32
X$KELTOSD 28 2013/8/16 9:32
X$KELTGSD 7 2013/8/16 9:32
X$KELRTD 129 2013/8/16 9:32
X$KELRXMR 3 2013/8/16 9:32
X$KELRSGA 1 2013/8/16 9:32
X$KEHR 82 2013/8/16 9:32
X$KEHPRMMAP 24 2013/8/16 9:32
X$KEHRP 38 2013/8/16 9:32
X$KEHSQT 63 2013/8/16 9:32
X$KEHSYSMAP 10 2013/8/16 9:32
X$KEHOSMAP 9 2013/8/16 9:32
X$KEHTIMMAP 19 2013/8/16 9:32
X$KEHR_CHILD 86 2013/8/16 9:32
X$KDNSSF 472 2013/8/16 9:32
X$KDXST 0 2013/8/16 9:32
X$KDXHS 16 2013/8/16 9:32
X$KEAOBJT 26 2013/8/16 9:32
X$KEACMDN 49 2013/8/16 9:32
X$KEHETSX 9 2013/8/16 9:32
X$KEHF 119 2013/8/16 9:32
X$KEHEVTMAP 105 2013/8/16 9:32
X$KEHECLMAP 12 2013/8/16 9:32
X$KECPDENTRY 0 2013/8/16 9:32
X$KECPRT 0 2013/8/16 9:32
X$KEAFDGN 84 2013/8/16 9:32
X$KCVFH 10 2013/8/16 9:32
X$KCVFHTMP 1 2013/8/16 9:32
X$KDLU_STAT 216 2013/8/16 9:32
X$KDLT 1 2013/8/16 9:32
X$KCVDF 10 2013/8/16 9:32
X$KCTICW 1 2013/8/16 9:32
X$KCTLAX 0 2013/8/16 9:32
X$KCRMF 0 2013/8/16 9:32
X$KCRMT 0 2013/8/16 9:32
X$KCRMX 0 2013/8/16 9:32
X$KCRRDSTAT 31 2013/8/16 9:32
X$KCRFX 0 2013/8/16 9:32
X$KCRRLNS 0 2013/8/16 9:32
X$KCRRNHG 3050 2013/8/16 9:32
X$KCRRASTATS 31 2013/8/16 9:32
X$KCRRARCH 30 2013/8/16 9:32
X$KCMSCN 1 2013/8/16 9:32
X$KCRFWS 1 2013/8/16 9:32
X$KCRFSTRAND 53 2013/8/16 9:32
X$KCPDBINC 0 2013/8/16 9:32
X$KCLQN 0 2013/8/16 9:32
X$KCLRCVST 1 2013/8/16 9:32
X$KCPXPL 20 2013/8/16 9:32
X$KCRFDEBUG 1 2013/8/16 9:32
X$KCFTIO 200 2013/8/16 9:32
X$KCLFX 0 2013/8/16 9:32
X$KCLLS 0 2013/8/16 9:32
X$KCLCRST 1 2013/8/16 9:32
X$KCFISTCAP 0 2013/8/16 9:32
X$KCLCURST 1 2013/8/16 9:32
X$KCLDELTAST 0 2013/8/16 9:32
X$KCFISTSA 11 2013/8/16 9:32
X$KCLPINGPIN 2048 2013/8/16 9:32
X$KCCRSP 0 2013/8/16 9:32
X$KCCRSR 9 2013/8/16 9:32
X$KCFIOHIST 28 2013/8/16 9:32
X$KCFIOFCHIST 0 2013/8/16 9:32
X$KCFIO 200 2013/8/16 9:32
X$KCCRS 42 2013/8/16 9:32
X$KCCRT 1 2013/8/16 9:32
X$KCCTIR 8 2013/8/16 9:32
X$KCCSL 0 2013/8/16 9:32
X$KCCTF 1 2013/8/16 9:32
X$KCCTS 11 2013/8/16 9:32
X$KCFISOSS 0 2013/8/16 9:32
X$KCFISOSSN 0 2013/8/16 9:32
X$KCFISOSSL 0 2013/8/16 9:32
X$KCFISOSST 0 2013/8/16 9:32
X$KCFISOSSC 0 2013/8/16 9:32
X$KCFISCAP 5 2013/8/16 9:32
X$KCCIC 2 2013/8/16 9:32
X$KCCRDI 1 2013/8/16 9:32
X$KCCIRT 1 2013/8/16 9:32
X$KCCNRS 0 2013/8/16 9:32
X$KCCPDB 0 2013/8/16 9:32
X$KCCLE 99 2013/8/16 9:32
X$KCCPA 0 2013/8/16 9:32
X$KCCRM 1 2013/8/16 9:32
X$KCCLH 70 2013/8/16 9:32
X$KCCOR 0 2013/8/16 9:32
X$KCCRL 0 2013/8/16 9:32
X$KCCPD 0 2013/8/16 9:32
X$KCCFN 18 2013/8/16 9:32
X$KCCBI 1 2013/8/16 9:32
X$KCCDL 1 2013/8/16 9:32
X$KCCDFHIST 0 2013/8/16 9:32
X$KCCBLKCOR 0 2013/8/16 9:32
X$KCCCP 8 2013/8/16 9:32
X$KCCCF 2 2013/8/16 9:32
X$KCCDI 1 2013/8/16 9:32
X$KCCDI2 1 2013/8/16 9:32
X$KCCFE 10 2013/8/16 9:32
X$KCCAL 3 2013/8/16 9:32
X$KCCBS 2 2013/8/16 9:32
X$KCCBP 2 2013/8/16 9:32
X$KCCBF 2 2013/8/16 9:32
X$KCCBL 0 2013/8/16 9:32
X$KCCDC 0 2013/8/16 9:32
X$KCCFC 0 2013/8/16 9:32
X$KCCCC 0 2013/8/16 9:32
X$KCCFLE 0 2013/8/16 9:32
X$KCCAGF 1 2013/8/16 9:32
X$KCCACM 9 2013/8/16 9:32
X$KCCADFC 0 2013/8/16 9:32
X$KCBWDS 32 2013/8/16 9:32
X$KCBVBL 0 2013/8/16 9:32
X$KCBWH 1300 2013/8/16 9:32
X$KCBUWHY 1300 2013/8/16 9:32
X$KCBWAIT 19 2013/8/16 9:32
X$KCBWBPD 9 2013/8/16 9:32
X$KCBSW 1300 2013/8/16 9:32
X$KCBTEK 11 2013/8/16 9:32
X$KCBMKID 1 2013/8/16 9:32
X$KCBPRFH 0 2013/8/16 9:32
X$KCBOBH 31016 2013/8/16 9:32
X$KCBMMAV 0 2013/8/16 9:32
X$KCBLSC 64 2013/8/16 9:32
X$KCBPINTIME 2048 2013/8/16 9:32
X$KCBSC 21 2013/8/16 9:32
X$KCBSDS 32 2013/8/16 9:32
X$KCBOQH 1849 2013/8/16 9:32
X$KCBBHS 0 2013/8/16 9:32
X$KCBBES 19 2013/8/16 9:32
X$KCBKWRL 1 2013/8/16 9:32
X$KCBKPFS 400 2013/8/16 9:32
X$KCBBF 3000 2013/8/16 9:32
X$KCBFWAIT 400 2013/8/16 9:32
X$KAUVRSTAT 1 2013/8/16 9:32
X$KBRPSTAT 5 2013/8/16 9:32
X$KCBLDRHIST 1000 2013/8/16 9:32
X$K2GTE2 0 2013/8/16 9:32
X$KCBDWS 1 2013/8/16 9:32
X$KCBDWOBJ 0 2013/8/16 9:32
X$KCBFCIO 0 2013/8/16 9:32
X$KCBDBK 1 2013/8/16 9:32
X$K2GTE 0 2013/8/16 9:32
X$IR_RS_PARAM 0 2013/8/16 9:32
X$JSKJOBQ 1 2013/8/16 9:32
X$JSKSLV 0 2013/8/16 9:32
X$JSKMIMRT 0 2013/8/16 9:32
X$IR_WR_PARAM 0 2013/8/16 9:32
X$IR_WORKING_FAILURE_SET 0 2013/8/16 9:32
X$IR_WORKING_REPAIR_SET 0 2013/8/16 9:32
X$IR_REPAIR_OPTION 0 2013/8/16 9:32
X$IR_REPAIR_STEP 0 2013/8/16 9:32
X$IR_WF_PARAM 0 2013/8/16 9:32
X$JSKMIMMD 0 2013/8/16 9:32
X$GIMSA 24 2013/8/16 9:32
X$INSTANCE_CACHE_TRANSFER 0 2013/8/16 9:32
X$ESTIMATED_MTTR 1 2013/8/16 9:32
X$GLOBALCONTEXT 0 2013/8/16 9:32
X$HEATMAPSEGMENT 19 2013/8/16 9:32
X$IR_MANUAL_OPTION 0 2013/8/16 9:32
X$HOFP 0 2013/8/16 9:32
X$IEE 0 2013/8/16 9:32
X$IEE_ORPIECE 0 2013/8/16 9:32
X$IEE_CONDITION 0 2013/8/16 9:32
X$DURABLE_SHARDED_SUBS 0 2013/8/16 9:32
X$HS_SESSION 0 2013/8/16 9:32
X$DRM_HISTORY 0 2013/8/16 9:32
X$DRM_HISTORY_STATS 0 2013/8/16 9:32
X$DNFS_STATS 0 2013/8/16 9:32
X$DUAL 1 2013/8/16 9:32
X$DRA_FAILURE 75 2013/8/16 9:32
X$DRA_FAILURE_PARAM 189 2013/8/16 9:32
X$DRA_FAILURE_REPAIR_MAP 116 2013/8/16 9:32
X$DRA_REPAIR_PARAM 73 2013/8/16 9:32
X$DRA_FAILURE_REPAIR 264 2013/8/16 9:32
X$DRA_FAILURE_CHECK 53 2013/8/16 9:32
X$DRA_FAILURE_CHECK_MAP 107 2013/8/16 9:32
X$DRA_FAILURE_PARENT_MAP 11 2013/8/16 9:32
X$DRA_REPAIR 112 2013/8/16 9:32
X$DNFS_FILES 0 2013/8/16 9:32
X$DNFS_CHANNELS 0 2013/8/16 9:32
X$DNFS_HIST 0 2013/8/16 9:32
X$DNFS_SERVERS 0 2013/8/16 9:32
X$DNFS_META 1 2013/8/16 9:32
X$DIAG_INFO 11 2013/8/16 9:32
X$DGLPARAM 36 2013/8/16 9:32
X$DGLXDAT 0 2013/8/16 9:32
X$DBKRECO 0 2013/8/16 9:32
X$DBKRUN 6 2013/8/16 9:32
X$DIR 15 2013/8/16 9:32
X$DBKINCMETCFG 1 2013/8/16 9:32
X$DBKINCMETSUMMARY 1 2013/8/16 9:32
X$DBKINCMETINFO 0 2013/8/16 9:32
X$DBKEFEFC 18 2013/8/16 9:32
X$DBKH_CHECK_PARAM 63 2013/8/16 9:32
X$DBKFDG 20 2013/8/16 9:32
X$DBKFSET 0 2013/8/16 9:32
X$DBKINFO 51 2013/8/16 9:32
X$DBKH_CHECK 38 2013/8/16 9:32
X$DBKEFIEFC 512 2013/8/16 9:32
X$CON_KSLSCS 13 2013/8/16 9:32
X$CON_KSLEI 1567 2013/8/16 9:32
X$CON_KSUSGSTA 839 2013/8/16 9:32
X$CKPTBUF 25664 2013/8/16 9:32
X$CONTEXT 0 2013/8/16 9:32
X$CON 1 2013/8/16 9:32
X$CON_KEWSSYSV 34 2013/8/16 9:32
X$DBKEFAFC 7 2013/8/16 9:32
X$DBKEFDEAFC 0 2013/8/16 9:32
X$DBKECE 40 2013/8/16 9:32
X$CELL_NAME 0 2013/8/16 9:32
X$BUFFERED_SUBSCRIBERS 0 2013/8/16 9:32
X$BH 33749 2013/8/16 9:32
X$BMAPNONDURSUB 32 2013/8/16 9:32
X$BUFFER 0 2013/8/16 9:32
X$BUFFERED_PUBLISHERS 0 2013/8/16 9:32
X$BUFFER2 0 2013/8/16 9:32
X$BUFFERED_QUEUES 0 2013/8/16 9:32
X$AUD_OBJ_ACTIONS 19 2013/8/16 9:32
X$AUD_XS_ACTIONS 48 2013/8/16 9:32
X$AUD_OLS_ACTIONS 19 2013/8/16 9:32
X$ASH 581 2013/8/16 9:32
X$AUD_DP_ACTIONS 4 2013/8/16 9:32
X$AUD_DPAPI_ACTIONS 3 2013/8/16 9:32
X$AUD_DV_OBJ_EVENTS 14 2013/8/16 9:32
X$ACTIVECKPT 9 2013/8/16 9:32
X$ABSTRACT_LOB 1 2013/8/16 9:32
X$AQ_SUBSCRIBER_LOAD 0 2013/8/16 9:32
X$QESRSTATALL 7137 2013/8/16 9:32
X$QESRSTAT 0 2013/8/16 9:32
X$QESRCOBJ 0 2013/8/16 9:32
X$QESRCMEM 0 2013/8/16 9:32
X$QESRCDEP 0 2013/8/16 9:32
X$QESRCMSG 0 2013/8/16 9:32
X$QESRCDR 0 2013/8/16 9:32
X$QESRCSTA 13 2013/8/16 9:32
X$QESRCRR 0 2013/8/16 9:32
X$QESMMSGA 38 2013/8/16 9:32
X$QESMMIWT 0 2013/8/16 9:32
X$QESMMIWH 33 2013/8/16 9:32
X$QESMMAPADV 14 2013/8/16 9:32
X$QESRCRD 0 2013/8/16 9:32
X$KQLSET 2689 2013/8/16 9:32
X$QESBLSTAT 20 2013/8/16 9:32
X$QESMMAHIST 462 2013/8/16 9:32
X$KQLFXPL 7099 2013/8/16 9:32
X$KQLFSQCE 714215 2013/8/16 9:32
X$KKSSRD 1720 2013/8/16 9:32
X$KKSSQLSTAT 2956 2013/8/16 9:32
X$KQLFBC 2281 2013/8/16 9:32
X$KKSAI 0 2013/8/16 9:32
X$KKSCS 1704 2013/8/16 9:32
X$KKSBV 2281 2013/8/16 9:32
X$KGLXS 4253 2013/8/16 9:32
X$KGLTR 750 2013/8/16 9:32
X$KGLSIM 18 2013/8/16 9:32
X$KGLOB 15849 2013/8/16 9:32
X$KGLRD 6578 2013/8/16 9:32
X$KGLST 269 2013/8/16 9:32
X$KGLSN 37 2013/8/16 9:32
X$KGLPN 29 2013/8/16 9:32
X$KGLNA1 53213 2013/8/16 9:32
X$KGLLK 436 2013/8/16 9:32
X$KGLAU 478 2013/8/16 9:32
X$KGLDP 5312 2013/8/16 9:32
X$KGLNA 53196 2013/8/16 9:32
X$KGLJSIM 10 2013/8/16 9:32
X$KGLMEM 126 2013/8/16 9:32
X$KGLJMEM 126 2013/8/16 9:32

 

 

  procedure gather_fixed_objects_stats
    (stattab varchar2 default null, statid varchar2 default null,
     statown varchar2 default null,
     no_invalidate boolean default
       to_no_invalidate_type(get_param('NO_INVALIDATE')));
--
-- Gather statistics for fixed tables.
-- To run this procedure, you must have the SYSDBA or ANALYZE ANY DICTIONARY
-- system privilege.
--
-- Input arguments:
--   stattab - The user stat table identifier describing where to save
--      the current statistics.
--   statid - The (optional) identifier to associate with these statistics
--      within stattab.
--   statown - The schema containing stattab (if different then ownname)
--   no_invalidate - Do not invalide the dependent cursors if set to TRUE.
--      The procedure invalidates the dependent cursors immediately
--      if set to FALSE.
--      Use DBMS_STATS.AUTO_INVALIDATE to have oracle decide when to
--      invalidate dependend cursors. This is the default. The default
--      can be changed using set_param procedure.
-- Exceptions:
--   ORA-20000: insufficient privileges
--   ORA-20001: Bad input value
--   ORA-20002: Bad user statistics table, may need to upgrade it
--

  function report_gather_fixed_obj_stats
    (stattab varchar2 default null, statid varchar2 default null,
     statown varchar2 default null,
     no_invalidate boolean default
       to_no_invalidate_type(get_param('NO_INVALIDATE')),
     detail_level varchar2 default 'TYPICAL',
     format varchar2 default 'TEXT')
  return clob;

--
-- This procedure runs gather_fixed_objects_stats in reporting mode. That is,
-- stats are not actually collected, but all the objects that will be
-- affected when gather_fixed_objects_stats is invoked are reported.
-- The detail level for the report is defined by the detail_level
-- input parameter. Please see the comments for report_single_stats_operation
-- on possible values for detail_level and format.
-- For all other input parameters, please see the comments on
-- gather_fixed_objects_stats.

  procedure delete_fixed_objects_stats(
        stattab varchar2 default null, statid varchar2 default null,
        statown varchar2 default null,
        no_invalidate boolean default
        to_no_invalidate_type(get_param('NO_INVALIDATE')),
        force boolean default FALSE);
--
-- Deletes statistics for fixed tables
-- To run this procedure, you must have the SYSDBA or ANALYZE ANY DICTIONARY
-- system privilege.
--
-- Input arguments:
--   stattab - The user stat table identifier describing from where
--      to delete the statistics.  If stattab is null, the statistics
--      will be deleted directly in the dictionary.
--   statid - The (optional) identifier to associate with these statistics
--      within stattab (Only pertinent if stattab is not NULL).
--   statown - The schema containing stattab (if different then ownname)
--   no_invalidate - Do not invalide the dependent cursors if set to TRUE.
--      The procedure invalidates the dependent cursors immediately
--      if set to FALSE.
--      Use DBMS_STATS.AUTO_INVALIDATE to have oracle decide when to
--      invalidate dependend cursors. This is the default. The default
--      can be changed using set_param procedure.
--   force - Ignores the statistics lock on objects and delete
--           the statistics if set to TRUE.
--
-- Exceptions:
--   ORA-20000: insufficient privileges
--   ORA-20002: Bad user statistics table, may need to upgrade it
--

  procedure export_fixed_objects_stats(
        stattab varchar2, statid varchar2 default null,
        statown varchar2 default null);
--
-- Retrieves statistics for fixed tables and stores them in the user
-- stat table identified by stattab
-- To run this procedure, you must have the SYSDBA or ANALYZE ANY DICTIONARY
-- system privilege.
--
-- Input arguments:
--   stattab - The user stat table identifier describing where
--      to store the statistics.
--   statid - The (optional) identifier to associate with these statistics
--      within stattab.
--   statown - The schema containing stattab (if different then ownname)
--
-- Exceptions:
--   ORA-20000: insufficient privileges
--   ORA-20002: Bad user statistics table, may need to upgrade it
--

  procedure import_fixed_objects_stats(
        stattab varchar2, statid varchar2 default null,
        statown varchar2 default null,
        no_invalidate boolean default
           to_no_invalidate_type(get_param('NO_INVALIDATE')),
        force boolean default FALSE);
--
-- Retrieves statistics for fixed tables from the user stat table and
-- stores them in the dictionary
-- To run this procedure, you must have the SYSDBA or ANALYZE ANY DICTIONARY
-- system privilege.
-- The statistics will be imported as pending in case PUBLISH preference
-- is set to FALSE.
--
-- Input arguments:
--   stattab - The user stat table identifier describing from where
--      to retrieve the statistics.
--   statid - The (optional) identifier to associate with these statistics
--      within stattab.
--   statown - The schema containing stattab (if different then ownname)
--   no_invalidate - Do not invalide the dependent cursors if set to TRUE.
--      The procedure invalidates the dependent cursors immediately
--      if set to FALSE.
--      Use DBMS_STATS.AUTO_INVALIDATE to have oracle decide when to
--      invalidate dependend cursors. This is the default. The default
--      can be changed using set_param procedure.
--   force - Override statistics lock.
--     TRUE- Ignores the statistics lock on objects and import
--           the statistics.
--     FALSE-The statistics of an object will be imported only if it
--           is not locked.
--
-- Exceptions:
--   ORA-20000: insufficient privileges
--              if ORA-20000 shows "no statistics are imported", several
--              possible reasons are: (1) user specified statid does not
--              exist; (2) statistics are locked; (3) objects in the
--              stattab no longer exist in the current database
--   ORA-20001: Invalid or inconsistent values in the user stat table
--   ORA-20002: Bad user statistics table, may need to upgrade it

Oracle SQL优化之自动 SQL 优化

  • 描述语句概要分析
  • 使用 SQL 优化指导
  • 使用 SQL 访问指导
  • 使用自动 SQL 优化

自动优化 SQL 语句

  • 自动优化 SQL 语句可简化 SQL 优化的整个过程,并取代手动 SQL 优化。
  • 优化程序模式:

–正常模式

–优化模式或自动优化优化程序 (ATO)

  • SQL 优化指导用于访问优化模式。
  • 应仅对高负载的 SQL 语句使用优化模式。

自动优化 SQL 语句是查询优化程序自动执行整个 SQL 优化过程的功能。此自动过程取代了复杂、重复且费时的手动 SQL 优化功能。SQL 优化指导向用户公开了 SQL 优化的功能。增强的查询优化程序有两种模式:

  • 在正常模式下,优化程序编译 SQL 并生成执行计划。正常模式下的优化程序会为绝大多数的 SQL 语句生成一个合理的执行计划。在正常模式下,优化程序遵循非常严格的时间约束条件,通常为一秒钟的若干分之几,在此期间它必须找到一个有效的执行计划。
  • 在优化模式下,优化程序执行更多分析,检查是否可以进一步改善在正常模式下生成的执行计划。在优化模式下查询优化程序的输出并不是一个执行计划,而是一系列操作及其理由和预期优点(用于生成一个有明显优势的更好计划)。在优化模式下调用的优化程序被称为自动优化优化程序 (ATO)。ATO 执行的优化被称为系统 SQL 优化。

在优化模式下,优化程序可以用几分钟的时间来优化单条语句。对于对整个系统产生重要影响的高负载的复杂 SQL 语句,应使用 ATO。

 

应用程序优化面临的挑战

 

应用程序优化面临的挑战

甚至对于专家而言,确定高负载 SQL 语句并对其进行优化也是一项非常具有挑战性的任务。SQL 优化不仅是数据库服务器性能管理最重要的方面之一,而且也是最难完成的任务之一。从 Oracle Database 10g 开始,确定高负载 SQL 语句的任务由自动数据库诊断监视器 (ADDM) 自动执行。虽然 ADDM 识别的高负载 SQL 语句数量可能只占 SQL 总工作量的一个非常小的百分比,但优化这些语句的任务仍十分复杂,需要具有高水平的专业
知识。

此外,SQL 优化活动是一项持续进行的任务,因为在部署新应用程序模块时 SQL 工作量通常发生相对更改。

Oracle Database 10g 引入的 SQL 优化指导旨在取代手动优化 SQL 语句的过程。消耗大量资源(例如 CPU、I/O 和临时空间)的 SQL 语句是 SQL 优化指导的目标对象。该指导接收一条或多条 SQL 语句作为输入后,会提供有关优化执行计划的建议、该建议的理由、估计的性能改善以及实施建议的实际命令。您可以接受建议,从而优化 SQL 语句。引入 SQL 优化指导后,您现在可以让 Oracle 优化程序为您优化 SQL 代码。

 

SQL 优化指导:概览

SQL 优化指导:概览

 

SQL 优化指导主要是用作优化过程的驱动者。它通过调用自动优化优化程序 (ATO) 来执行以下四种特定类型的分析:

  • 统计信息分析:ATO 检查每个查询对象,确定是否缺少统计信息,或统计信息是否已过时,然后提出收集相关统计信息的建议。同时它还收集辅助信息,以便在无法实施建议的情况下提供缺少的统计信息或更正过时统计信息。
  • SQL 概要分析:ATO 会验证它自身的估计值并收集辅助信息以消除估计错误。同时它还根据 SQL 语句的过去执行历史记录,以自定义优化程序设置(例如第一批行和所有行)的形式收集辅助信息。它使用辅助信息构建一个 SQL 概要文件并提出创建 SQL 概要文件的建议。创建 SQL 概要文件后,此概要文件以正常模式启用查询优化程序,以生成经过良好优化的计划。
  • 访问路径分析:ATO 会检查新索引是否可明显地改进查询中每个表的访问性能,并且在适当的时候提供创建这种索引的建议。
  • SQL 结构分析:在这里,ATO 会尝试确定导致不佳计划的 SQL 语句,并提供相关建议来调整它们。建议的调整可能是对 SQL 代码的语法更改,也可能是语义更改。

过时或缺少的对象统计信息

 

  • 对于优化程序而言,对象统计信息是关键输入。
  • ATO 验证每个查询对象的对象统计信息。
  • ATO 使用动态采样,并生成以下内容:

–辅助对象统计信息,用于弥补缺少的或修正过时的对象
统计信息

–收集合适的对象统计信息的建议:

DBMS_STATS.GATHER_TABLE_STATS(
ownname=>’SH’, tabname=>’CUSTOMERS’,estimate_percent=>DBMS_STATS.AUTO_SAMPLE_SIZE);

 

查询优化程序依赖对象统计信息生成执行计划。如果统计信息已过时或缺少统计信息,则优化程序得不到所需的必要信息,因而生成的执行计划可能不是最理想的。

ATO 检查每个查询对象,确定其是否缺少统计信息或统计信息是否已过时,并生成两种类型的输出:

  • 统计信息形式的辅助信息(适用于没有统计信息的对象)和统计信息调整系数(适用于具有过时统计信息的对象)
  • 为具有过时统计信息或没有统计信息的对象收集相关统计信息的建议

为了获得最佳效果,您应在获得建议时收集统计信息,然后重新运行自动优化程序。但是,如果接受此建议,可能会对系统中的其它查询产生影响,这一点可能令您对是否立即接受建议有所顾虑。

 

SQL 语句概要分析

  • 对于优化程序而言,统计信息是关键输入。
  • ATO 验证语句统计信息,例如:

–谓词选择性

–优化程序设置(FIRST_ROWS 与 ALL_ROWS)

  • 自动优化优化程序使用以下方法和对象:

–动态采样

–执行语句的一部分

–语句的过去执行历史记录统计信息

  • 如果已生成了统计信息,ATO 会构建一个概要文件:

exec :profile_name :=    dbms_sqltune.accept_sql_profile( task_name =>’my_sql_tuning_task‘);

在 SQL 概要分析期间,主要验证步骤是验证查询优化程序自己所估计的被优化语句的成本、选择性和基数。

在 SQL 概要分析期间,ATO 执行验证步骤,以验证自己的估计值。验证包括对数据进行采样,并对样本应用适当的谓词。对新估计值和常规估计值进行比较,如果区别足够大,则应用更正系数。另一种估计值验证方法需要执行 SQL 语句的一部分。在各自谓词都提供有效的访问路径时,部分执行方法比采样方法更高效。ATO 选择适当的估计值验证
方法。

ATO 还可以使用 SQL 语句的过去执行历史记录来确定正确的设置。例如,如果执行历史记录表明在多数时候仅部分执行 SQL 语句,则 ATO 使用 FIRST_ROWS 优化,而不使用
ALL_ROWS。

如果在统计信息分析或 SQL 概要分析期间生成了辅助信息,则 ATO 会构建 SQL 概要文件。在构建 SQL 概要文件后,它会生成一个创建 SQL 概要文件的用户建议。

在此模式下,ATO 可能会建议接受生成的 SQL 概要文件,以将其激活。

 

计划优化流程和 SQL 概要文件创建

计划优化流程和 SQL 概要文件创建

SQL 概要文件是在自动优化 SQL 语句期间构建的辅助信息集合。因此,SQL 概要文件与 SQL 语句对应,而统计信息与表或索引对应。创建概要文件之后,正常模式下的查询优化程序将 SQL 概要文件与现有统计信息结合在一起使用,为相应 SQL 语句生成经过良好优化的计划。SQL 概要文件将永久存储在数据字典中。但是,常规字典视图不会显示 SQL 概要文件信息。在创建 SQL 概要文件后,每次在正常模式下编译相应 SQL 语句时,查询优化程序就会使用 SQL 概要文件生成经过良好优化的计划。

幻灯片显示了创建和使用 SQL 概要文件的流程。此流程包括两个不同阶段:系统 SQL 优化阶段和常规优化阶段。在系统 SQL 优化阶段中,您可以使用 Oracle Enterprise Manager Database Control 或命令行界面选择要进行系统优化的 SQL 语句,并运行 SQL 优化指导。SQL 优化指导会调用 ATO 生成优化建议(ATO 可能会使用 SQL 概要文件)。如果已构建了 SQL 概要文件,则您可以接受它。接受 SQL 概要文件后,此概要文件会存储在数据字典中。在下一阶段,当最终用户发出相同 SQL 语句时,查询优化程序(在正常模式下)会使用 SQL 概要文件构建一个经过良好优化的计划。SQL 概要文件的使用过程对于最终用户是完全透明的,并且不需要对应用程序源代码进行更改。

 

SQL 优化循环

SQL 优化循环

 

SQL 概要文件中包含的辅助信息以特定方式进行存储,在数据库发生更改(如添加或删除索引、表大小增长以及定期收集数据库统计信息)后这些信息仍保持相关。所以,在创建概要文件时,不会冻结相应计划(如在使用大纲时)。

但是,SQL 概要文件可能不再适应数据库中发生的大量更改或者在很长一段时间内累积起来的更改。在这种情况下,需要构建新的 SQL 概要文件,以取代旧的概要文件。

例如,当 SQL 概要文件已过时时,相应 SQL 语句的性能可能会显著变差。在这种情况下,相应 SQL 语句可能会开始表现为高负载或顶级 SQL 语句,因而会再次成为系统 SQL 优化的目标。在这样的情形下,ADDM 会再次将此语句捕获为高负载 SQL。如果发生此情况,您可能决定为该语句重新创造一个新的概要文件。

 

访问路径分析

 

访问路径分析

ATO 还提供有关索引的建议。有效地编制索引是一种广为人知的优化技术,该技术可以通过减少对全表扫描的需求来显著提高 SQL 语句的性能。ATO 生成的任何索引建议都专用于正在进行优化的 SQL 语句。所以,对于与单个 SQL 语句相关的性能问题,它可以提供快速解决方案。

由于 ATO 并不对索引建议会如何影响整个 SQL 工作量执行分析,所以建议对典型 SQL 工作量中的 SQL 语句运行访问指导。访问指导将收集为 SQL 工作量中每条语句提供的建议,并将其合并成对整体 SQL 工作量的全局建议。

访问路径分析可以提供以下建议:

  • 如果新索引能显著改善性能,则创建新索引。
  • 运行 SQL 访问指导,基于应用程序工作量执行全面的索引分析。

 

SQL 结构分析

SQL 结构分析

SQL 结构分析的目标是帮助确定编写不当的 SQL 语句,并就如何调整这些语句提供建议。

语法上的某些变化会对性能产生负面影响。在此模式下,ATO 会根据一组规则对语句进行评估,确定效率较低的编码技术,并提供相应备选语句作为建议。建议可能与原始查询很相似,但不完全相同。例如,NOT EXISTS 和 NOT IN 构造器很相似,但不完全相同。所以,您必须自己确定建议是否有效。由于此原因,ATO 不自动重新编写查询,而是提供建议。

SQL 结构分析可以检测以下类别的问题:

  • SQL 构造器的使用,例如使用了 NOT IN,而不是 NOT EXISTS,或者使用了 UNION 而不是 UNION ALL
  • 谓词的使用,例如谓词涉及的索引列的数据类型不匹配,妨碍索引的使用
  • 设计错误(例如笛卡尔积)

SQL 优化指导:使用模型

SQL 优化指导:使用模型

SQL 优化指导可以接受一条或多条 SQL 语句作为输入。输入可以来自不同的来源:

  • ADDM 确定的高负载 SQL 语句
  • 当前在游标高速缓存中的 SQL 语句
  • 来自自动工作量资料档案库 (AWR) 的 SQL 语句:用户可以选择 AWR 捕获的任何 SQL 语句集。可以使用快照或基线完成此操作。
  • 自定义工作量:用户可以创建一个只包含用户感兴趣的语句的自定义工作量。这些语句可能不在游标高速缓存中,并且不是 ADDM 或 AWR 要捕获的高负载语句。对于这样的语句,用户可以创建一个自定义工作量,并使用指导对其进行优化。

可以对来自游标高速缓存、AWR 和自定义工作量的 SQL 语句进行过滤和排序,然后再将其输入到 SQL 优化指导中。

如果输入的语句有多条,则系统会提供一个名为 SQL 优化集 (STS) 的新对象。STS 可存储多条 SQL 语句及其执行信息:

  • 执行上下文:分析方案名称和绑定值
  • 执行统计信息:平均所用时间和执行计数

:创建 STS 时,可以将另一 STS 用作信息来源。

 

Database Control SQL 优化指导

Database Control 和 SQL 优化指导

从 Oracle Enterprise Manager 访问 SQL 优化指导最简单的方法是使用“Advisor Central(指导中心)”页。在主页中,单击位于“Related Links(相关链接)”部分中的“Advisor Central(指导中心)”链接打开“Advisor Central(指导中心)”页。

在“Advisor Central(指导中心)”页上,单击“SQL Advisors(SQL 指导)”链接。在“SQL Advisors(SQL 指导)”页中,单击“SQL Tuning Advisor(SQL 优化指导)”链接。此时将转到“Schedule SQL Tuning Advisor(调度 SQL 优化指导)”页。在此页中,您会发现到其它不同页的链接。单击“Top Activity(顶级活动)”链接打开“Top Activity(顶级活动)”页。

 

运行 SQL 优化指导:示例

运行 SQL 优化指导:示例

可以使用 Database Control 确定高负载或顶级 SQL 语句。可以从 Database Control 中的多个位置中为所确定的一条或多条 SQL 语句(即 STS)启动 SQL 优化指导:

  • 优化 ADDM 确定的 SQL 语句:ADDM 的“Finding Details(查找结果详细资料)”页会显示 ADDM 确定的高负载 SQL 语句。其中每条高负载 SQL 语句都消耗一个或多个系统资源(例如 CPU 时间、缓冲区获取数、磁盘读取数等等)的很大一部分。可以使用此页对所选高负载 SQL 语句启动 SQL 优化指导。
  • 优化顶级 SQL 语句:另一个 SQL 源是顶级 SQL 语句列表。本幻灯片展示了这种情形。您可以通过查看在所选时间范围内累积的语句执行统计信息,确定顶级 SQL 语句的列表。用户可以选择由 SQL ID 标识的一条或多条顶级 SQL 语句,并对其启动
    SQL 优化指导。
  • 优化一个 SQL 优化集:还可以查看不同用户创建的不同 STS。可能已通过从 AWR 创建的一系列快照中选择 SQL 语句,或通过选择自定义 SQL 语句,基于顶级 SQL 语句列表创建了 STS。

 

实施建议

实施建议

启动 SQL 优化指导之后,Oracle Enterprise Manager 会自动创建优化任务,前提是用户有相应的 ADVISOR 权限来执行此操作。Oracle Enterprise Manager 在“Schedule SQL Tuning Advisor(调度 SQL 优化指导)”页上显示优化任务及其自动默认设置,如上一张幻灯片所示。在此页上,用户可以更改与优化任务相关的自动默认设置。

其中一个重要选项是选择优化任务的范围。如果选择“Limited(有限制)”选项,SQL 优化指导会根据统计信息检查、访问路径分析和 SQL 结构分析来生成建议。将范围设为“Limited(有限制)”时不会生成 SQL 概要文件建议。如果选择“Comprehensive(综合)”选项,SQL 优化指导不仅会执行“Limited(有限制)”范围下的所有建议,如果适用,还会在 SQL 概要分析模式下调用优化程序来构建 SQL 概要文件。使用“Comprehensive(综合)”选项时,还可以指定优化任务的时间限制,这个时间限制的默认值是 30 分钟。另一个有用的选项是立即运行优化任务,或将其安排在以后的时间运行。

可以在“Schedule Advisor(调度指导)”页配置优化任务。要执行此操作,请选择“Schedule SQL Tuning Advisor(调度 SQL 优化指导)”操作,然后单击“Go(执行)”返回“Top Activity(顶级活动)”页后,您可以单击优化过的语句,打开“SQL Details(SQL 详细资料)”页,以便查看优化信息。
这会显示已完成的优化任务。通过单击此任务,可以查看其常规 SQL 优化结果。通过单击“View(查看)”按钮,可以查看其详细资料。如图所示,已创建了 SQL 概要文件;在查看了新计划后,如果需要,则可以实施它。

 

SQL 访问指导:概览

SQL 访问指导:概览

如何定义适当的访问结构以优化 SQL 查询一直是开发人员所关心的问题。因此,为了解决该问题,相关人员已经写了大量的论文和脚本,还开发了一些高端工具。此外,随着分区和实体化视图技术的发展,确定访问结构也变得更加复杂。
作为 Oracle Database 10g  和 11g 中的可管理性增强功能的一部分,引入了 SQL 访问指导来解决这个非常关键的需求。

SQL 访问指导可以建议要创建、删除或保留的索引、实体化视图、实体化视图日志或分区,从而确定并帮助解决与执行 SQL 语句相关的性能问题。可以从 Database Control 或者从命令行使用 PL/SQL 过程来运行 SQL 访问指导。

SQL 访问指导可以接受实际工作量作为输入,或者根据方案推导出一个假想工作量。然后,它会推荐合适的访问结构以使用速度较快的执行路径。SQL 访问指导具有以下优点:

  • 不需要拥有专业知识
  • 根据基于成本的优化程序 (CBO) 中实际存在的规则做决定
  • 与优化程序以及 Oracle DB 增强功能同步
  • 是涵盖 SQL 访问方法所有方面的单个指导
  • 提供用户友好的简单 GUI 向导
  • 生成可用于实施建议的脚本

SQL 访问指导:使用模型

SQL 访问指导:使用模型

SQL 访问指导可接受从以下多个来源派生而来的工作量作为输入:

  • SQL 高速缓存,接受 V$SQL 的当前内容
  • 假想工作量,根据维模型生成一个可能工作量。在初始设计系统时,这个选项比较
    有用
  • SQL 优化集,来自工作量资料档案库

SQL 访问指导还提供强大的工作量过滤功能,可用于确定优化目标。例如,用户可以指定 SQL 访问指导只观察工作量中 30 个资源最密集的语句(根据优化程序开销确定)。对于指定的工作量,SQL 访问指导随后会执行以下操作:

  • 同时考虑索引解决方案、实体化视图解决方案、分区解决方案或者全部三个解决方案的组合
  • 考虑存储的创建和维护成本
  • 不为部分工作量生成删除建议
  • 优化实体化视图以最大化查询重写使用率和快速刷新
  • 建议用于快速刷新的实体化视图日志
  • 建议对表、索引和实体化视图进行分区
  • 将类似的索引组合为单个索引
  • 生成支持多个工作量查询的建议

可能的建议

建议 综合 有限制
对表或实体化视图添加新的(分区的)索引。
删除未使用的索引。
通过更改索引类型修改现有索引。
通过在末尾添加列修改现有的索引。
添加新的(分区的)实体化视图。
删除未使用的实体化视图(日志)。
添加新的实体化视图日志。
修改现有的实体化视图日志以添加新列或子句。
对现有的未分区表或索引进行分区。

 

SQL 访问指导会仔细考虑建议的整体影响,并仅使用已知的工作量和提供的信息生成建议。可以使用两种工作量分析方法:

  • 综合:SQL 访问指导通过这种方法解决优化分区、实体化视图、索引和实体化视图日志的所有方面。SQL 访问指导假定工作量包含一个完整的有代表性的应用程序 SQL 语句集。
  • 有限制:与综合工作量方法不同,有限制的工作量方法假定工作量仅包含有问题的 SQL 语句。因此,将寻求提高一部分应用程序环境性能的建议。

如果选择了综合工作量分析,则 SQL 访问指导将生成一个较好的全局优化优化集,但所需分析时间会比较长。如表中所示,选择的工作量方法决定了 SQL 访问指导生成的建议类型。

:仅对至少包含 10,000 行的表和在 NUMBER 或 DATE 类型的列上有一些谓词或联接的工作量给出分区建议。只能针对这些类型的列生成分区建议。此外,只能为单列间隔分区和散列分区生成分区建议。间隔分区建议可能输出为范围语法,但默认值是间隔。执行散列分区只是为了利用智能化分区联接。

SQL 访问指导会话:初始选项

SQL 访问指导会话:初始选项

接下来的几张幻灯片将介绍一个典型的 SQL 访问指导会话。可以通过单击数据库主页上的“Advisor Central(指导中心)”链接访问 SQL 访问指导,也可以通过单个预警页或性能页进行访问,这些页可能包含用于帮助解决性能问题的链接。SQL 访问指导包括多个步骤,可在执行这些步骤的过程中提供要优化的 SQL 语句,以及要使用的访问方法类型。

在“SQL Access Advisor: Initial Options(SQL 访问指导: 初始选项)”页中,可以在启动向导前选择用来填充默认选项的模板或任务。可以单击“Continue(继续)”启动向导,或者单击“Cancel(取消)”返回到“Advisor Central(指导中心)”页。

:在生成建议的过程中,SQL 访问向导可以被打断,从而允许您查看结果。

有关使用 SQL 访问指导的常规信息,请参阅《Oracle Data Warehousing Guide》“SQL Access Advisor”一课中的“Overview of the SQL Access Advisor”部分。

 

SQL 访问指导会话:初始选项1

如果在“Initial Options(初始选项)”页上选择了“Inherit Options from a Task or Template(从任务或模板继承选项)”选项,则可以选择一个现有的任务或模板以继承 SQL 访问指导的选项。默认情况下,将使用 SQLACCESS_EMTASK 模板。

通过选择相应的对象并单击“View Options(查看选项)”,可以查看任务或模板定义的各种选项。

 

SQL 访问指导:工作量来源

SQL 访问指导:工作量来源

可以从三个不同的来源中选择工作量来源:

  • Current and Recent SQL Activity(当前和最近的 SQL 活动):此来源对应于仍缓存在系统全局区 (SGA) 中的 SQL 语句。
  • Use an existing SQL Tuning Set(使用现有的 SQL 优化集):您也可以创建并使用存放语句的 SQL 优化集。
  • Hypothetical Workload(假想的工作量):此选项将提供允许指导搜索维表并生成工作量的方案。此来源在初始设计方案时很有用。

使用“Filter Options(过滤选项)”部分可以进一步过滤工作量来源。过滤选项有:

  • Resource Consumption(资源消耗):按优化程序成本、缓冲区获取数、CPU 时间、磁盘读取数、所用时间、执行数排序的语句数量
  • Users(用户)
  • Tables(表)
  • SQL Text(SQL 文本)
  • Module IDs(模块 ID)
  • Actions(操作)

SQL 访问指导:建议选项

SQL 访问指导:建议选项

在“Recommendations Options(建议选项)”页中,可以选择是否限制 SQL 访问指导基于单个访问方法提出建议。可以选择 SQL 访问指导要推荐的结构的类型。如果没有选择三个可能值中的任何一个,则 SQL 访问指导将评估现有的结构,而不尝试推荐新结构。

可以使用“Advisor Mode(指导模式)”部分,以两种模式之一运行指导。这些模式会影响建议的质量和处理所需的时间。在“Comprehensive Mode(综合模式)”中,指导将搜索候选的大型池,以便得到最高质量的建议。在“Limited Mode(限制模式)”中,SQL 访问指导将快速执行,通过仅处理最高成本的语句来限制候选建议。

:可以单击“Advanced Options(高级选项)”以显示或隐藏选项,这些选项可用于设置空间限制、优化选项和默认存储位置。

SQL 访问指导:安排和复查

SQL 访问指导:安排和复查

SQL 访问指导:结果

SQL 访问指导:结果

通过“Advisor Central(指导中心)”页,可以检索用于您的分析的任务详细资料。通过选择“Advisor Central(指导中心)”页上“Results(结果)”部分中的任务名称,可以访问“Results for Task(任务结果)”的“Summary(概要)”页;可在此页上看到 SQL 访问指导查找结果的概览。该页中显示了图表和统计信息,为建议提供了整体工作量性能和改善查询执行时间方面的可能性。使用该页可以显示语句计数和建议操作计数。

SQL 访问指导:结果和实施

SQL 访问指导:结果和实施

要查看 SQL 访问指导任务结果的其它方面,可单击该页上其它三个选项卡之一:“Recommendations(建议)”、“SQL Statements(SQL 语句)”或“Details(详细
资料)”。

在“Recommendation(建议)”页上,可以细化到各个建议。对于其中的每个建议,可以查看“Select Recommendations for Implementation(选择要实施的建议)”表中的重要信息。然后,可以选择一个或多个建议,并安排实施。

如果单击特定建议的 ID,则将进入“Recommendation(建议)”页,该页显示了指定建议的所有操作,可以根据需要修改语句的表空间名称。完成了任何更改后,单击“OK(确定)”将应用更改。在“Recommendation(建议)”页中,可以查看一个操作的完整文本,方法是单击指定操作的“Action(操作)”字段中的链接。单击“Show SQL(显示 SQL)”可以查看建议中所有操作的 SQL。

“SQL Statements(SQL 语句)”页(本幻灯片没有显示此页)显示了一个图表和一个对应的表,其中列出了最初按成本改善程度由高到低排序的 SQL 语句。最上面的 SQL 语句通过实施关联建议可得到最大程度的改善。

“Details(详细资料)”页显示了创建任务时所用的工作量和任务选项。此页还提供了在任务执行过程中记录的所有日记条目。

还可以通过单击“Schedule Implementation(安排实施)”按钮来安排建议的实施。

SQL 优化循环

SQL 优化循环1

Oracle Database 10g 引入了 SQL 优化指导,用于帮助应用程序开发人员改善 SQL 语句的性能。该指导用于解决 SQL 编写不当这一问题;这些 SQL 语句没有采用最有效的方式进行设计。此外,该优化指导还可以解决 SQL 语句执行效果较差的问题(此问题较常见),对于这些 SQL 语句,优化程序由于缺乏精确的相关数据统计信息而生成了较差的执行计划。在所有情况下,该指导都会提供具体的建议来提高 SQL 性能,但是否实施建议由用户决定。

除了 SQL 优化指导以外,Oracle Database 10g 还有一个自动进程,可确定系统中的高负载 SQL 语句。ADDM 就是这样的进程,它可自动确定应进行优化的高负载 SQL 语句。

但是,还是存在一些重要问题:虽然 ADDM 确实可以确定一些应该进行优化的 SQL,但用户仍必须手动查看 ADDM 报表,然后根据这些报表运行 SQL 优化指导以进行优化。

自动 SQL 优化

自动 SQL 优化

Oracle Database 11g 可以确定有问题的 SQL 语句,对这些语句运行 SQL 优化指导,并实施获得的 SQL 概要文件建议来优化语句,不需要用户的干预,因而进一步提高了 SQL 优化进程的自动化程度。自动 SQL 优化通过在默认情况下每晚运行的名为“自动 SQL 优化”的新任务使用 AUTOTASK 框架。下面简要描述了 Oracle Database 11g 中的自动 SQL 优化过程:

  • 步骤 1:根据 AWR 顶级 SQL 标识(在以下四个不同时间段处于顶级的 SQL:过去一周、过去一周中的任何一天、过去一周中的任何一小时或者单个响应时间),自动 SQL 优化可以确定自动优化目标。
  • 步骤 2 和 3:在维护窗口中执行自动 SQL 优化任务时,将通过调用 SQL 优化指导自动优化以前确定的 SQL 语句。因此,如果需要,将为这些语句创建 SQL 概要文件。但是,在做出决定之前,需要认真测试新的概要文件。
  • 步骤 4:您在任何时间点都可以请求有关这些自动优化活动的报表。
    然后,可以选择检查优化的 SQL 语句以验证或删除生成的自动 SQL 概要文件。

 

自动优化过程

自动优化过程

在优化过程中,将考虑并报告所有建议类型,但只能自动实施 SQL 概要文件(ACCEPT_SQL_PROFILES 任务参数设置为 TRUE 时)。在其它情况下,仅在自动 SQL 优化报表中报告创建 SQL 概要文件的建议。

在 Oracle Database 11g 中,性能改善系数必须至少等于三,才会实施 SQL 概要文件。正如我们所看到的,自动 SQL 优化过程仅自动实施 SQL 概要文件建议。在 SQL 优化过程中会生成其它建议(用于创建新索引、刷新过时统计信息或调整 SQL 语句),但并不实施这些建议。您需要对这些建议进行检查,然后在适当的情况下手动实施。

下面简要描述了常规自动优化过程:

优化以语句为单位执行。因为只能实施 SQL 概要文件,所以不需要考虑此类建议对工作量的整体影响。对于每条语句(按重要性排序),优化过程将执行以下各个步骤:

  1. 使用 SQL 优化指导优化语句。查找 SQL 概要文件;如果找到了此概要文件,则验证其基础优化程序统计信息是否为最新。
  1. 如果建议了某个 SQL 概要文件,则执行以下操作:

-通过在使用该建议和不使用该建议两种情况下执行语句,测试新的 SQL 概要
文件。

-如果生成了 SQL 概要文件,并且该文件导致优化程序为该语句选择了一个不同的执行计划,则优化指导必须确定是否实施 SQL 概要文件。优化指导将根据幻灯片中的流程图做出决定。虽然此处的性能提高阈值适用于 CPU 时间和输入/输出 (I/O) 时间的总和,但是,如果其中任意一方的统计信息表现出性能下降,就不会接受 SQL 概要文件。因此,要求 CPU 时间和 I/O 时间的总和改善三倍,并且其中任意一方的统计信息中没有表现出性能下降。通过这种方式,语句的运行速度将比不使用概要文件时快,即使出现 CPU 或 I/O 的争用情况也是如此。

  1. 如果发现了过时或丢失的统计信息,则将此类信息提供 GATHER_STATS_JOB。

自动实施优化建议仅适用于 SQL 概要文件,因为 SQL 概要文件的风险较小,还原实施很容易。

:所有 SQL 概要文件都是以标准 EXACT 模式创建的。系统会根据 CURSOR_SHARING 参数的当前值匹配和跟踪这些概要文件。您负责为工作量正确地设置 CURSOR_SHARING。

 

自动 SQL 优化控制

  • 自动任务配置:

–打开/关闭开关

–运行优化任务的维护窗口

–优化任务的 CPU 资源消耗

  • 任务参数:

–SQL 概要文件实施自动/手动开关

–优化任务的全局时间限制

–优化任务的每个 SQL 的时间限制

–禁用测试-执行模式以节省时间

–为每个执行以及从整体上自动实施的最大 SQL 概要
文件数

–任务执行有效期

 

 

以下是自动 SQL 优化任务的一个 PL/SQL 控制示例:

BEGIN
dbms_sqltune.set_tuning_task_parameter(‘SYS_AUTO_SQL_TUNING_TASK’, ‘LOCAL_TIME_LIMIT’, 1400);
dbms_sqltune.set_tuning_task_parameter(‘SYS_AUTO_SQL_TUNING_TASK’, ‘ACCEPT_SQL_PROFILES’, ‘TRUE’);
dbms_sqltune.set_tuning_task_parameter(‘SYS_AUTO_SQL_TUNING_TASK’, ‘MAX_SQL_PROFILES_PER_EXEC’, 50);
dbms_sqltune.set_tuning_task_parameter(‘SYS_AUTO_SQL_TUNING_TASK’, ‘MAX_AUTO_SQL_PROFILES’, 10002);
END;
此示例中的最后三个参数仅在自动 SQL 优化任务中受支持。您还可以使用 LOCAL_TIME_LIMIT 或 TIME_LIMIT 之类的参数;这些参数是传统 SQL 优化任务的有效参数。一个重要的示例是通过使用 TEST_EXECUTE 参数,禁用测试-执行模式(以节省时间),并仅使用执行计划成本做出有关性能的决定。

此外,还可以控制自动 SQL 优化任务的运行时间以及允许使用的 CPU 资源。

 

自动 SQL 优化任务

自动 SQL 优化任务

如前所述,自动 SQL 优化是作为自动维护任务实施的;该任务本身称为“自动 SQL 优化”。在“Automated Maintenance Tasks(自动维护任务)”页中可以看到与最近运行的自动 SQL 优化任务相关的一些高级别信息:要打开此页,请在 Database Control 主页中单击“Server(服务器)”选项卡。在打开的“Server(服务器)”选项卡式页中,单击“Tasks(任务)”部分中的“Automated Maintenance Tasks(自动维护任务)”链接。

在“Automated Maintenance Tasks(自动维护任务)”页上,可以看到预定义的任务。然后,单击相应的链接访问每个任务,获取有关任务本身的详细信息(如幻灯片中所示)。单击“Automatic SQL Tuning(自动 SQL 优化)”链接或最近的执行的图标(时间表上的绿色区域)时,“Automatic SQL Tuning Result Summary(自动 SQL 优化结果概要)”页就会打开。

 

配置自动 SQL 优化

配置自动 SQL 优化

可以使用“Automatic SQL Tuning Settings(自动 SQL 优化设置)”页配置各种自动 SQL 优化参数。

要定位至该页,请单击“Automated Maintenance Tasks(自动维护任务)”页上的“Configure(配置)”按钮。此时您会看到“Automated Maintenance Tasks Configuration(自动维护任务配置)”页,可在其中查看 Oracle Database 11g 提供的各种维护窗口。

默认情况下,自动 SQL 优化可在 MAINTENANCE_WINDOW_GROUP 中的所有预定义维护窗口上运行。可以针对一周中的特定日期禁用自动 SQL 优化。在此页上,还可以编辑每个窗口以更改其特性,方法是单击“Edit Window Group(编辑窗口组)”按钮。

要定位至“Automatic SQL Tuning Settings(自动 SQL 优化设置)”页,请在“Task Setting(任务设置)”部分中单击与“Automatic SQL Tuning(自动 SQL 优化)”对应的行上的“Configure(配置)”按钮。

在“Automatic SQL Tuning Settings(自动 SQL 优化设置)”页上,可以指定幻灯片中显示的参数。默认情况下,“Automatic Implementation of SQL Profiles(自动实施 SQL 概要文件)”处于未选中状态。

:如果将 STATISTICS_LEVEL 设置为 BASIC,使用 BMS_WORKLOAD_REPOSITORY 关闭 AWR 快照,或者 AWR 保留期限少于七天,也会停止自动 SQL 优化。

 

自动 SQL 优化:结果概要

自动 SQL 优化:结果概要

此外,“Automatic SQL Tuning Result Summary(自动 SQL 优化结果概要)”页还包含各种概要图形,您可以用来控制自动 SQL 优化任务。幻灯片中显示了一个示例。“Overall Task Statistics(总体任务统计信息)”部分的第一个图形按指定时段的查找结果类型显示细分。通过选择“Time Period(时段)”列表中的值,可以控制要为其生成报表的时段。示例中使用了“Customized(定制)”,显示的是最近一次运行。可以选择“All(所有)”涵盖迄今为止该任务的所有执行。用户可以请求过去一个月中任何时段的运行,因为这是优化指导保留其优化历史记录的时间期限。然后,单击“View Report(查看报表)”生成报表。

在“Breakdown by Finding Type(按照查找结果细分)”图形上,可以清楚地看到仅 SQL 概要文件可以实施。虽然还推荐了许多其它概要文件,但并非所有概要文件都被自动实施,原因如前所述。类似地,创建索引的建议以及其它类型的建议不会被实施。但是,如果希望以后实施这些建议,优化指导会保留与所有这些建议有关的历史信息。

在“Profile Effect Statistics(概要文件效果统计信息)”部分,可以看到“Tuned SQL DB Time Benefit(优化后的 SQL DB 时间优势)”图形,该图形显示了实施概要文件和其它建议前后的 DB 时间。

 

自动 SQL 优化:结果详细资料

自动 SQL 优化:结果详细资料

在“Automatic SQL Tuning Result Details(自动 SQL 优化结果详细资料)”页上,还可以看到各个自动优化的 SQL 语句的重要信息,包括语句的 SQL 文本和 SQL ID、SQL 优化指导执行的建议类型、经过验证的性能提高百分比、是否自动实施了特定建议以及建议的日期等。

在此页中,可以单击 SQL 语句的相应 SQL ID 链接细化到 SQL 语句本身;也可以选择其中一条 SQL 语句,然后单击“View Recommendations(查看建议)”按钮,了解有关该语句的建议的其它详细资料。

:所显示的每个建议的性能提高百分比是使用以下公式得出的:
bnf% = (time_old – time_new)/(time_old)。使用此公式,您可以看出三倍性能优势(例如,time_old = 100、time_new = 33)的对应值为 66%。因此,该系统实施所有性能提高超过 66% 的概要文件。根据此公式,98% 表示获得 50 倍的优势。

自动 SQL 优化结果详细资料:细化

自动 SQL 优化结果详细资料:细化

在“Recommendations for SQL ID(以下 SQL ID 的建议)”页上,可以看到对应的建议,可以手动实施这些建议。

单击“SQL Test(SQL 测试)”链接可以访问“SQL Details(SQL 详细资料)”页;在此页上可以看到优化历史记录以及与 SQL 语句关联的计划控制。

在幻灯片中,可以看到自动 SQL 优化已经优化了该语句,并且已自动实施了关联的概要文件。

 

自动 SQL 优化注意事项

  • 自动 SQL 优化不考虑的 SQL:

–临时 SQL 或极少重复的 SQL

–并行查询

–概要分析后长时间运行的查询

–递归 SQL 语句

–DML 和 DDL

  • 仍可使用 SQL 优化指导对上述语句进行手动优化。

自动 SQL 优化并不力求解决系统中出现的所有 SQL 性能问题。它不考虑以下类型的 SQL:

  • 临时 SQL 或极少重复的 SQL:如果某条 SQL 不以相同的形式执行多次,则优化指导将忽略该语句。在一周内没有重复出现的 SQL 也不在考虑之列。
  • 并行查询。
  • 长时间运行的查询(概要分析后):如果某个查询在经过 SQL 概要分析后运行的时间太长,则进行测试-执行就不很实际,因此优化指导将其忽略。请注意,这并不意味着优化指导将忽略所有长时间运行的查询。如果优化指导可以找到一个 SQL 概要文件,让原本花费几小时的查询在几分钟内运行,则可能接受此概要文件,因为仍然可以进行测试-执行。优化指导会用足够长的时间执行旧计划,确定旧计划劣于新计划后,就会终止测试-执行而不等待旧计划完成,并因此切换执行的顺序。
  • 递归 SQL 语句
  • DML,例如 INSERT SELECT 或 CREATE TABLE AS SELECT

除了真正的临时 SQL,上述限制仅适用于自动 SQL 优化。仍可手动运行 SQL 优化指导对上述语句进行优化。

 

 

ORACLE SQL优化器HINT介绍

在适当的时候使用提示HINT

  • 为以下项指定提示HINT:
  • 优化程序模式
    • 查询转换
    • 访问路径
    • 联接顺序
    • 联接方法

 

优化程序提示HINT:概览

优化程序提示HINT:

  • 影响优化程序的决定
  • 示例:

SELECT /*+ INDEX(e empfirstname_idx) skewed col */ *

FROM employees e

WHERE first_name=’David’

  • 不到万不得已,不要使用提示HINT
  • 使用提示HINT时,同时添加有关该提示HINT的注释是一个好习惯。

 

通过提示HINT,您可以左右优化程序所做的决定。提示HINT提供了一种机制,用以指示优化程序基于特定标准选择特定查询执行计划。

例如,您可能知道某个索引对于特定查询更具可选性。基于此信息,您可能能够选择一个比优化程序推荐的计划更高效的执行计划。在这种情况下,应使用提示HINT强制优化程序使用最佳执行计划。幻灯片示例展示了这种情况,在示例中强制优化程序使用 EMPFIRSTNAME_IDX 索引检索数据。正如您所看到的,您可以在 SQL 语句中使用注释将指令传递给优化程序。

加号 (+) 会使系统将注释解释为提示HINT列表。加号必须紧跟在注释分隔符之后,不留空格。

应少用提示HINT,仅在收集了相关表的统计信息,并使用 EXPLAIN PLAN 语句评估了没有提示HINT的优化程序计划后使用。在后续版本中,变化的数据库条件以及查询性能增强对代码中的提示HINT如何影响性能产生了重要影响。

另外,使用提示HINT还涉及必须进行管理、检查和控制的额外代码。

 

提示HINT类型

单表提示HINT 指定用于一个表或一个视图
多表提示HINT 指定用于多个表或视图
查询块提示HINT 作用于单个查询块
语句提示HINT 应用于整个 SQL 语句

 

 

单表:单表提示HINT指定用于一个表或一个视图。INDEX 和 USE_NL 是单表提示HINT的示例。

多表:除了指定用于一个或多个表或视图,多表提示HINT类似于单表提示HINT。LEADING 是一个多表提示HINT的示例。

查询块:查询块提示HINT作用于单个查询块。STAR_TRANSFORMATION 和 UNNEST 是查询块提示HINT的示例。

语句:语句提示HINT应用于整个 SQL 语句。ALL_ROWS 是语句提示HINT的示例。

注: USE_NL(table1 table2) 不是多表提示HINT,因为它实际上是 USE_NL(table1) 和 USE_NL(table2) 的快捷方式。

 

指定提示HINT

提示HINT仅应用于一个语句块的优化:

  • 针对表的自包含 DML 语句
  • 顶层 DML 或子查询

oracle_sql_hint1

 

提示HINT仅应用于其所在语句块的优化。语句块包括:

  • 简单的 MERGE、SELECT、INSERT、UPDATE 或 DELETE 语句
  • 父语句或复杂语句的子查询
  • 使用集合运算符(UNION、MINUS、INTERSECT)的复合查询的一部分

例如,使用 UNION 运算符将两个组件查询组合在一起即构成一个复合查询,该复合查询有两个块,每个组件查询使用一个块。因此,第一个组件查询中的提示HINT仅应用于其自身的优化,而不应用于第二个组件查询的优化。

优化程序提示HINT语法

将提示HINT包在 SQL 语句的注释内。可以使用两种注释样式中的任意一种。提示HINT分隔符 (+) 必须紧跟在注释分隔符之后。如果它们之间留有空格,则优化程序无法识别包含提示HINT的
注释。

 

提示HINT规则

  • 提示HINT应紧跟在语句块的第一个 SQL 关键字之后。
  • 每个语句块只能有一个提示HINT注释,但该注释可以包含多个提示HINT。
  • 提示HINT仅应用于其所在语句块。
  • 如果语句使用别名,则提示HINT必须引用别名,而不是表名称。
  • 优化程序忽略没有正确指定的提示HINT,而不显示错误。
  • 必须使提示HINT注释紧跟在 SQL 语句块的第一个关键字(MERGE、SELECT、INSERT、DELETE 或 UPDATE)之后。
  • 一个语句块只能有一个包含提示HINT的注释,但可以在该注释内包含多个由空格分隔的
    提示HINT。
  • 提示HINT仅应用于其所在语句块,覆盖实例级或会话级的参数。
  • 如果 SQL 语句使用别名,则提示HINT必须引用别名,而不是表名称。

Oracle 服务器忽略没有正确指定的提示HINT。但是,请注意下列事实:

  • 您从不会收到错误消息。
  • 系统会考虑同一注释中的其它(正确指定的)提示HINT。
  • Oracle 服务器还忽略互相冲突的提示HINT的组合。

 

提示HINT建议

  • 请慎重使用提示HINT,因为它们会导致很高的维护负荷。
  • 当硬编码提示HINT的有效性降低时,请注意它们对性能的影响。
  • 不到万不得已,不使用提示HINT作为优化 SQL 语句的手段。
  • 提示HINT可能会阻止优化程序使用更好的执行计划。
  • 当数据库结构或内容发生变化时,提示HINT的有效性可能会降低(甚至无效)。

 

 

优化程序提示HINT语法:示例

UPDATE /*+ INDEX(p PRODUCTS_PROD_CAT_IX)*/  
products p 
SET   p.prod_min_price = 
        (SELECT  
         (pr.prod_list_price*.95) 
FROM products pr 
WHERE p.prod_id = pr.prod_id) 
WHERE p.prod_category = 'Men' 
AND   p.prod_status = 'available, on stock' 
/ 

 

显示了一个示例,其中的提示HINT建议基于成本的优化程序 (CBO) 使用索引。执行计划如下所示:

Execution Plan

———————————————————-

0      UPDATE STATEMENT Optimizer=ALL_ROWS (Cost=3 …)

1    0   UPDATE OF ‘PRODUCTS’

2    1     TABLE ACCESS (BY INDEX ROWID) OF ‘PRODUCTS’ (TABLE) (Cost…)

3    2      INDEX (RANGE SCAN) OF ‘PRODUCTS_PROD_CAT_IX’ (INDEX)

(cost…)

4    1     TABLE ACCESS (BY INDEX ROWID) OF ‘PRODUCTS’ (TABLE) (Cost…)
5    4       INDEX (UNIQUE SCAN) OF ‘PRODUCTS_PK’ (INDEX (UNIQUE))
(Cost=0 …)

示例中显示的提示HINT只有在名为 PRODUCTS_PROD_CAT_IX 的索引存在于 PRODUCTS 表的 PROD_CATEGORY 列中才起作用。

 

 

提示HINT类别

提示HINT可用于以下项:

  • 优化方法和目标
  • 访问路径
  • 查询转换
  • 联接顺序
  • 联接操作
  • 并行执行
  • 其它提示HINT

 

 

优化目标和方法

ALL_ROWS 选择一个基于成本的方法以获得最佳吞吐量
FIRST_ROWS(n) 指示 Oracle 服务器优化单条 SQL 语句以进行快速响应

 

注:ALTER SESSION…SET OPTIMIZER_MODE 语句不影响在 PL/SQL 内运行的 SQL。

 

ALL_ROWS:ALL_ROWS 提示HINT显式选择一个基于成本的方法来优化一个语句块,目标是获得最佳吞吐量。即,使资源总消耗降到最低。

FIRST_ROWS(n):FIRST_ROWS(n) 提示HINT(其中 n 是任意正整数)指示 Oracle 服务器优化单条 SQL 语句以进行快速响应。它指示服务器选择可最高效地返回前 n 行的计划。FIRST_ROWS 提示HINT是为了实现向后兼容性并保持计划稳定而保留的,该提示HINT针对最佳计划进行优化以返回第一个单行。在包含任何阻塞操作(如排序或分组)的 SELECT 语句块中,优化程序会忽略此提示HINT。不会为了获得最佳响应时间而优化此类语句,因为 Oracle DB 在返回第一个行之前必须检索该语句访问的所有行。如果在任何此类语句中指定此提示HINT,则数据库会以获得最佳吞吐量为目标进行优化。

如果在 SQL 语句中指定 ALL_ROWS 或 FIRST_ROWS(n) 提示HINT,并且数据字典中没有有关该语句访问的表的统计信息,则优化程序会使用默认统计值估计缺少的统计信息,随后选择一个执行计划。

如果与 ALL_ROWS 或 FIRST_ROWS(n) 提示HINT一起指定了用于访问路径或联接操作的提示HINT,则优化程序会优先处理提示HINT指定的访问路径和联接操作。

注:FIRST_ROWS 提示HINT很可能是最有用的提示HINT。

 

访问路径的提示HINT

FULL 执行全表扫描
CLUSTER 通过聚簇扫描访问表
HASH 通过散列扫描访问表
ROWID 按 ROWID 访问表
INDEX 以升序扫描索引
INDEX_ASC 以升序扫描索引
INDEX_COMBINE 显式选择位图访问路径

 

 

只有某个索引存在从而确保指定访问路径的可用且访问路径位于 SQL 语句的语法结构中时,指定以上提示HINT之一才会促使优化程序选择指定的访问路径。如果提示HINT指定了一个不可用的访问路径,则优化程序会忽略它。您必须指定当出现在语句中时可以正确进行访问的表。如果语句使用表的别名,则提示HINT中应使用别名,而不是表名。如果语句中出现方案名称,则提示HINT中的表名不应包括方案名称。

FULL:FULL 提示HINT显式为指定表选择全表扫描。例如:

SELECT /*+ FULL(e) */ employee_id, last_name

FROM hr.employees e WHERE last_name LIKE ‘K%’;

Oracle 服务器对 employees 表执行全表扫描以执行此语句,即使 last_name 列上存在由 WHERE 子句中的条件启用的索引。

CLUSTER:CLUSTER 提示HINT指示优化程序使用聚簇扫描访问指定表。此提示HINT仅适用于聚
簇表。

HASH:HASH 提示HINT指示优化程序使用散列扫描访问指定表。此提示HINT仅适用于存储在表聚簇中的表。

ROWID:ROWID 提示HINT显式为指定表选择按 ROWID 扫描表。

 

INDEX:INDEX 提示HINT显式为指定表选择索引扫描。您可以为域、B* 树、位图和位图联接索引使用 INDEX 提示HINT。但是,最好为位图索引使用 INDEX_COMBINE 而不是 INDEX,因为前者是更通用的提示HINT。此提示HINT可根据需要指定一个或多个索引。

如果此提示HINT指定一个可用索引,则优化程序会按此索引执行扫描。优化程序不考虑执行全表扫描,也不按表中的其它索引执行扫描。

如果此提示HINT指定了一个可用索引列表,则优化程序会考虑按列表中的各个索引执行扫描的成本,然后执行成本最低的索引扫描。如果这样的访问路径具有最低成本,优化程序还会选择扫描此列表中的多个索引,并合并结果。优化程序不考虑执行全表扫描,也不按提示HINT中没有列出的索引进行扫描。

如果此提示HINT未指定任何索引,则优化程序会考虑按表的每个可用索引扫描的成本,然后执行成本最低的索引扫描。如果这样的访问路径具有最低成本,优化程序还会选择扫描多个索引,并合并结果。优化程序不考虑执行全表扫描。

INDEX_ASC:INDEX_ASC 提示HINT显式为指定表选择索引扫描。如果语句使用索引范围扫描,Oracle 服务器会按其索引值的升序扫描索引条目。由于服务器对范围扫描的默认行为是按其索引值的升序扫描索引条目,因此此提示HINT指定的内容不比 INDEX 提示HINT指定的多。但是,如果此默认行为发生更改,则您也许需要使用 INDEX_ASC 提示HINT显式指定升序的范围扫描。

INDEX_DESC:INDEX_DESC 提示HINT指示优化程序为指定表使用降序索引扫描。如果语句使用索引范围扫描,并且索引是升序的,则系统按其索引值的降序扫描索引条目。在分区索引中,结果按降序排列在各个分区中。对于降序索引,此提示HINT可有效消除降序,实现按升序扫描索引条目。

INDEX_COMBINE:INDEX_COMBINE 提示HINT显式为表选择位图访问路径。如果没有为 INDEX_COMBINE 提示HINT提供索引作为参数,则优化程序会为表使用具有最佳估计成本的位图索引布尔型组合。如果提供了某些索引作为参数,则优化程序会尝试使用这些特定位图索引的某种布尔型组合。

例如:

SELECT /*+INDEX_COMBINE(customers cust_gender_bix cust_yob_bix)*/ *

FROM customers WHERE cust_year_of_birth < 70 AND cust_gender = ‘M’;

注:INDEX、INDEX_FFS 和 INDEX_SS 具有反义提示HINT,分别为 NO_INDEX、NO_INDEX_FFS 和 NO_INDEX_SS,用于防止使用这些路径。

 

访问路径的提示HINT

INDEX_JOIN 指示优化程序使用索引联接作为访问路径
INDEX_DESC 为指定表选择索引扫描
INDEX_FFS 执行快速完全索引扫描
INDEX_SS 执行索引跳过扫描
NO_INDEX 不允许使用索引集
AND_EQUAL 合并单列索引

 

INDEX_JOIN:INDEX_JOIN 提示HINT显式地指示优化程序使用索引联接作为访问路径。为了让提示HINT产生积极的影响,索引的数目要尽可能少,但必须包括解析查询所必需的列的所有索引。

例如,下列查询使用索引联接访问 employee_id 和 department_id 列,这两列在员工表中都已被编制索引。

SELECT /*+index_join(employees emp_emp_id_pk emp_department_ix)*/ employee_id, department_id
FROM hr.employees WHERE department_id > 50;

INDEX_DESC:INDEX_DESC 提示HINT显式为指定表选择索引扫描。如果语句使用索引范围扫描,则 Oracle 服务器将按索引值的降序扫描索引条目。在分区索引中,结果按降序排列在各个分区中。

例如:

SELECT /*+ INDEX_DESC(a ord_order_date_ix) */ a.order_date, a.promotion_id, a.order_id
FROM oe.orders a WHERE a.order_date < ’01-jan-1985′;

 

INDEX_FFS:INDEX_FFS 提示HINT会导致执行快速完全索引扫描,而不是全表扫描。

例如:

SELECT /*+ INDEX_FFS ( o order_pk ) */ COUNT(*)
FROM order_items l, orders o
WHERE l.order_id > 50 AND l.order_id = o.order_id;

INDEX_SS:INDEX_SS 提示HINT指示优化程序为指定表的指定索引执行索引跳过扫描。如果语句使用索引范围扫描,则系统将按索引值的升序扫描索引条目。在分区索引中,结果按升序排列在各个分区中。还有 INDEX_SS_ASC 和 INDEX_SS_DESC 提示HINT。

NO_INDEX:NO_INDEX 提示HINT显式禁止指定表使用索引集。

  • 如果此提示HINT指定了单个可用索引,则优化程序将不考虑按此索引执行扫描,但仍考虑其它没有指定的索引。
  • 如果此提示HINT指定了一个可用索引列表,则优化程序将不考虑按其中的任何指定索引执行扫描,但仍考虑列表中没有指定的其它索引。
  • 如果此提示HINT没有指定任何索引,则优化程序不考虑按表的任何索引执行扫描。这种行为与指定了表的所有可用索引列表的 NO_INDEX 提示HINT的行为相同。

NO_INDEX 提示HINT适用于基于函数的索引、B* 树索引、位图索引或域索引。如果 NO_INDEX 提示HINT和某个索引提示HINT(INDEX、INDEX_ASC、INDEX_DESC、 INDEX_COMBINE 或 INDEX_FFS)同时指定了相同的索引,则这些指定索引的 NO_INDEX 提示HINT和索引提示HINT都会被忽略,优化程序会考虑这些指定的索引。

例如:

SELECT /*+NO_INDEX(employees emp_empid)*/ employee_id
FROM employees WHERE employee_id > 200;

AND_EQUAL:AND_EQUAL 提示HINT显式选择一个执行计划,该计划使用可合并几个单列索引的扫描的访问路径,在该路径中您可以指定:

  • 与要合并的索引相关联的表的名称或别名。
  • 要执行索引扫描的索引。必须至少指定两个索引,但不能多于五个。

 

INDEX_COMBINE 提示HINT:示例

SELECT –+INDEX_COMBINE(CUSTOMERS)

       cust_last_name

FROM  SH.CUSTOMERS

WHERE ( CUST_GENDER= ‘F’ AND

CUST_MARITAL_STATUS =  ‘single’)

OR     CUST_YEAR_OF_BIRTH BETWEEN ‘1917’ 
AND ‘1920’;

 

INDEX_COMBINE 提示HINT设计用于位图索引操作。请牢记以下内容:

  • 如果为提示HINT提供了某些索引作为参数,则优化程序会尝试使用这些特定位图索引的某种组合。
  • 如果提示HINT中没有列出任何索引,则认为所有索引都包含在提示HINT中。
  • 优化程序总是尝试使用提示HINT的索引,无论它们是否具有成本效益。

在幻灯片的示例中,假定幻灯片中语句的 WHERE 谓词引用的三个列(CUST_MARITAL_STATUS、CUST_GENDER 和 CUST_YEAR_OF_BIRTH)都有一个位图索引。启用 AUTOTRACE 时,语句的执行计划可以显示出来,如下一张幻灯片所示。

 

INDEX_COMBINE 提示HINT:示例

 

Execution Plan

—————————————————

|   0 | SELECT STATEMENT              |

|   1 |  TABLE ACCESS BY INDEX ROWID  | CUSTOMERS

|   2 |   BITMAP CONVERSION TO ROWIDS |

|   3 |    BITMAP OR                  |

|   4 |     BITMAP MERGE              |

|   5 |      BITMAP INDEX RANGE SCAN  | CUST_YOB_BIX

|   6 |     BITMAP AND                |

|   7 |      BITMAP INDEX SINGLE VALUE| CUST_MARITAL_BIX

|   8 |      BITMAP INDEX SINGLE VALUE| CUST_GENDER_BIX

 

 

查询转换的提示HINT

NO_QUERY_TRANSFORMATION 跳过所有查询转换
USE_CONCAT 将 OR 重写成 UNION ALL 并禁用 INLIST 处理
NO_EXPAND 阻止 OR 扩展
REWRITE 根据实体化视图重写查询
NO_REWRITE 关闭查询重写
UNNEST 将子查询主体合并到外围查询块中
NO_UNNEST 关闭取消嵌套

 

NO_QUERY_TRANSFORMATION:NO_QUERY_TRANSFORMATION 提示HINT指示优化程序跳过所有查询转换,包括但不限于 OR 扩展、视图合并、子查询取消嵌套、星形转换和实体化视图重写。

USE_CONCAT:USE_CONCAT 提示HINT使用 UNIONALL 集合运算符强制将查询的 WHERE 子句中的组合 OR 条件转换成复合查询。通常,只有当使用串联的查询成本比不使用串联的查询成本低时,才发生此转换。USE_CONCAT 提示HINT禁用 IN 列表处理。

NO_EXPAND:NO_EXPAND 提示HINT阻止基于成本的优化程序考虑为 WHERE 子句中有 OR 条件或 IN 列表的查询使用 OR 扩展。通常,优化程序会考虑使用 OR 扩展,如果它确定使用此方法的成本低于不使用此方法的成本,就会使用该方法。

REWRITE:REWRITE 提示HINT指示优化程序根据实体化视图在可能时重写查询,而不考虑成本。使用 REWRITE 提示HINT时,可以指定视图列表,也可以不指定视图列表。此课程不介绍实体化视图。

UNNEST:UNNEST 提示HINT允许优化程序在评估路径和联接时同时考虑子查询及其外围查询,指示优化程序对子查询取消嵌套,并将子查询主体合并到包围它的查询块的主体中。

 

查询转换的提示HINT 

MERGE 将复杂视图或子查询与其外围查询合并
NO_MERGE 阻止合并可合并的视图
STAR_TRANSFORMATION 让优化程序使用可在其中使用转换的最佳计划
FACT 指示应将被提示HINT表当作事实表
NO_FACT 指示不应将被提示HINT表当作事实表

 

MERGE:MERGE 提示HINT允许您为每个查询合并一个视图。如果某个视图的查询包含了 GROUP BY 子句或者在 SELECT 列表中使用了 DISTINCT 运算符,则只有启用了复杂视图合并时优化程序才能将视图的查询合并到正在访问的语句中。这是默认行为,但您可以使用 NO_MERGE 之类的提示HINT禁用此机制。也可以使用复杂合并将 IN 子查询合并到正在访问的语句中(如果该子查询没有关联)。

在不提供参数的情况下使用 MERGE 提示HINT时,应将该提示HINT放在视图查询块中。在提供视图名称作为参数的情况下使用 MERGE 时,应将该提示HINT放在外围查询中。

NO_MERGE:NO_MERGE 提示HINT会使 Oracle 服务器不合并可以被合并的视图。通过此提示HINT,用户可以对视图的访问方式施加更大的影响。在不提供参数的情况下使用 NO_MERGE 提示HINT时,应将该提示HINT放在视图查询块中。在提供视图名称作为参数的情况下使用 NO_MERGE 时,应将该提示HINT放在外围查询中。

 

STAR_TRANSFORMATION:STAR_TRANSFORMATION 提示HINT可使优化程序使用其中使用了转换的最佳计划。如果没有提示HINT,优化程序可能会基于成本作出决定,使用在没有转换时生成的最佳计划,而不使用已转换查询的最佳计划。

即使使用提示HINT,也不能保证转换一定会发生。优化程序仅在它认为合理时才生成子查询。如果没有生成子查询,则没有转换的查询,此时不管是否有提示HINT,都使用未转换查询的最佳计划。

FACT:FACT 提示HINT在星形转换上下文中使用,用于指示转换时应将被提示HINT表作为事实表。

NO_FACT:NO_FACT 提示HINT在星形转换上下文中使用,用于指示转换时不应将提示HINT表作为事实表。

 

联接顺序的提示HINT

ORDERED 使 Oracle 服务器按表在 FROM 子句中出现的顺序联接表
LEADING 将指定表用作联接顺序中的第一个表

 

下列提示HINT用于建议联接顺序:

ORDERED:ORDERED 使 Oracle 服务器按表在 FROM 子句中出现的顺序联接这些表。如果在执行联接的 SQL 语句中省略了 ORDERED 提示HINT,则优化程序会选择表的联接顺序。如果您知道某些信息(如从每个表选择多少行),而优化程序不了解这些信息,则可能需要使用 ORDERED 提示HINT指定联接顺序。以一个嵌套循环为例,最准确的方法是在 FROM 子句中按索引中的关键字的顺序排列这些表,大表放在最后。然后使用下列提示HINT:

/*+ ORDERED USE_NL(FACTS) INDEX(facts fact_concat) */

这里,facts 是表,而 fact_concat 是索引。更常用的方法是使用 STAR 提示HINT。

LEADING:LEADING 提示HINT指示优化程序在执行计划中首先联接指定的表集。如果由于联接图中的相关性,不能首先按照指定的顺序联接指定表,则忽略 LEADING 提示HINT。如果针对不同的表指定了两个或多个 LEADING 提示HINT,则所有提示HINT都将被忽略。如果指定了 ORDERED 提示HINT,则将覆盖所有 LEADING 提示HINT。

 

联接操作的提示HINT

USE_NL 使用嵌套循环联接来联接指定表
NO_USE_NL 不使用嵌套循环执行联接
USE_NL_WITH_INDEX 类似于 USE_NL,但必须能够将一个索引用于联接
USE_MERGE 使用排序合并联接来联接指定表
NO_USE_MERGE 不为联接执行排序合并操作
USE_HASH 使用散列联接来联接指定表
NO_USE_HASH 不使用散列联接
DRIVING_SITE 指示优化程序在数据库选择的站点之外的站点执行查询

 

这里描述的每个提示HINT都建议了一种针对表的联接操作。在提示HINT中,指定表的方式必须与在语句中指定表的方式完全相同。如果语句使用表的别名,则在提示HINT中必须使用该别名,而不是表名。但是,提示HINT中的表名称不应包含方案名称(如果语句中包含方案名称)。建议将 USE_NL 和 USE_MERGE 提示HINT与 ORDERED 提示HINT组合使用。当引用的表被强制成为联接的内部表时,Oracle 服务器使用这些提示HINT;如果引用的表是外部表,则忽略提示HINT。

USE_NL:USE_NL 提示HINT促使 Oracle 服务器使用嵌套循环联接(将指定表用作内部表)将每一个指定表与另一个行来源相联接。如果需要优化语句以获得最佳响应时间,或使返回查询所选的第一行所需的用时最小,而不是为了获得最佳吞吐量,则可以通过使用 USE_NL 提示HINT,强制优化程序选择嵌套循环联接。

USE_NL_WITH_INDEX:USE_NL_WITH_INDEX 提示HINT类似于 USE_NL 提示HINT。但是,如果没有指定索引,优化程序必须能够使用某个索引,且该索引使用至少一个联接谓词作为索引关键字。如果指定了索引,优化程序必须能够使用该索引,且该索引使用至少一个联接谓词作为索引关键字。

NO_USE_NL:NO_USE_NL 提示HINT促使优化程序排除嵌套循环联接。但是,在某些情况下只能使用嵌套循环来联接表。在这类情况下,优化程序将忽略这些表的提示HINT。

 

在许多情况下,嵌套循环联接能比排序合并联接更快地返回第一行。在从一个表中读取第一个选定行,从另一个表中读取第一个匹配行,然后将它们组合在一起后,嵌套循环联接即可以返回第一个行。但是排序合并联接需要读取两个表的所有选定行并对它们进行排序,将每个已排序行来源的第一行组合在一起,所有这些完成后才能返回第一行。

在下面的语句中,通过一个提示HINT强制实施了嵌套循环,通过全表扫描访问 orders,并将 l.order_id = h.order_id 筛选条件应用于每个行。针对满足筛选条件的每个行,都会通过索引 order_id 访问 order_items。

SELECT /*+ USE_NL(l h) */ h.customer_id, l.unit_price * l.quantity
FROM oe.orders h ,oe.order_items l
WHERE l.order_id = h.order_id;

在查询中添加 INDEX 提示HINT可以避免对 orders 执行全表扫描,这会导致执行计划类似于较大系统上使用的执行计划,即使在这里它可能并不是特别高效。

USE_MERGE:USE_MERGE 提示HINT促使 Oracle 服务器使用排序合并联接将每个指定表与另一个行来源联接,如下面的示例所示:

SELECT /*+USE_MERGE(employees departments)*/ * FROM employees, departments WHERE employees.department_id = departments.department_id;

NO_USE_MERGE:NO_USE_MERGE 提示HINT促使优化程序排除排序合并联接,并使用指定表作为内部表将每个指定表联接到另一个行来源。

USE_HASH:USE_HASH 提示HINT促使 Oracle 服务器使用散列联接将每个指定表与另一个行来源联接,如下例所示:

SELECT /*+USE_HASH(l l2) */ l.order_date, l.order_id,
l2.product_id, SUM(l2.unit_price*quantity)
FROM oe.orders l, oe.order_items l2
WHERE l.order_id = l2.order_id
GROUP BY l2.product_id, l.order_date, l.order_id;

下面是另一个示例:

SELECT /*+use_hash(employees departments)*/ *
FROM hr.employees, hr.departments
WHERE employees.department_id = departments.department_id;

NO_USE_HASH:NO_USE_HASH 提示HINT促使优化程序排除散列联接,并使用指定表作为内部表将每个指定表联接到另一个行来源。

DRIVING_SITE:此提示HINT指示优化程序在数据库选择的站点之外的站点执行查询。如果您使用分布式查询优化决定应在哪个站点执行联接,则此提示HINT很有用。

 

在许多情况下,嵌套循环联接能比排序合并联接更快地返回第一行。在从一个表中读取第一个选定行,从另一个表中读取第一个匹配行,然后将它们组合在一起后,嵌套循环联接即可以返回第一个行。但是排序合并联接需要读取两个表的所有选定行并对它们进行排序,将每个已排序行来源的第一行组合在一起,所有这些完成后才能返回第一行。

在下面的语句中,通过一个提示HINT强制实施了嵌套循环,通过全表扫描访问 orders,并将 l.order_id = h.order_id 筛选条件应用于每个行。针对满足筛选条件的每个行,都会通过索引 order_id 访问 order_items。

SELECT /*+ USE_NL(l h) */ h.customer_id, l.unit_price * l.quantity
FROM oe.orders h ,oe.order_items l
WHERE l.order_id = h.order_id;

在查询中添加 INDEX 提示HINT可以避免对 orders 执行全表扫描,这会导致执行计划类似于较大系统上使用的执行计划,即使在这里它可能并不是特别高效。

USE_MERGE:USE_MERGE 提示HINT促使 Oracle 服务器使用排序合并联接将每个指定表与另一个行来源联接,如下面的示例所示:

SELECT /*+USE_MERGE(employees departments)*/ * FROM employees, departments WHERE employees.department_id = departments.department_id;

NO_USE_MERGE:NO_USE_MERGE 提示HINT促使优化程序排除排序合并联接,并使用指定表作为内部表将每个指定表联接到另一个行来源。

USE_HASH:USE_HASH 提示HINT促使 Oracle 服务器使用散列联接将每个指定表与另一个行来源联接,如下例所示:

SELECT /*+USE_HASH(l l2) */ l.order_date, l.order_id,
l2.product_id, SUM(l2.unit_price*quantity)
FROM oe.orders l, oe.order_items l2
WHERE l.order_id = l2.order_id
GROUP BY l2.product_id, l.order_date, l.order_id;

下面是另一个示例:

SELECT /*+use_hash(employees departments)*/ *
FROM hr.employees, hr.departments
WHERE employees.department_id = departments.department_id;

NO_USE_HASH:NO_USE_HASH 提示HINT促使优化程序排除散列联接,并使用指定表作为内部表将每个指定表联接到另一个行来源。

DRIVING_SITE:此提示HINT指示优化程序在数据库选择的站点之外的站点执行查询。如果您使用分布式查询优化决定应在哪个站点执行联接,则此提示HINT很有用。

 

其它提示HINT

APPEND 启用直接路径 INSERT
NOAPPEND 启用常规 INSERT
ORDERED_PREDICATES 强制优化程序保留谓词计算顺序
CURSOR_SHARING_EXACT 阻止用绑定变量替换文字
CACHE 覆盖表的默认高速缓存规范
PUSH_PRED 将联接谓词推入视图
PUSH_SUBQ 首先计算未合并的子查询
DYNAMIC_SAMPLING 控制动态采样以改善服务器性能

 

APPEND:APPEND 提示HINT允许您在数据库以串行模式运行时启用直接路径 INSERT。如果使用的不是企业版,则数据库处于串行模式。常规 INSERT 是串行模式下的默认设置,而直接路径 INSERT 是并行模式下的默认模式。在直接路径 INSERT 中,数据被附加到表的末尾,而不使用当前分配给表的现有空间。因此,直接路径 INSERT 比常规 INSERT 快很多。

NOAPPEND:NOAPPEND 提示HINT通过在 INSERT 语句执行期间禁用并行模式来启用直接路径 INSERT。(常规 INSERT 是串行模式下的默认设置,而直接路径 INSERT 是并行模式下的默认模式。)

ORDERED_PREDICATES:ORDERED_PREDICATES 提示HINT强制优化程序保留谓词的计算顺序,但谓词被用作索引关键字时除外。可在 SELECT 语句的 WHERE 子句中使用此提示HINT。

 

如果不使用 ORDERED_PREDICATES 提示HINT,Oracle 服务器将按下列顺序计算所有谓词:

  1. 首先按照 WHERE 子句中指定的顺序计算不带用户定义函数、类型方法或子查询的
    谓词。
  2. 接下来按照成本的升序计算带用户定义函数的谓词和带具有用户计算成本的类型方法的谓词。
  3. 随后按 WHERE 子句中指定的顺序计算带用户定义函数的谓词和带没有用户计算成本的类型方法的谓词。
  4. 然后计算 WHERE 子句中没有指定的谓词(例如,优化程序生成的过渡性谓词)。
  5. 最后按 WHERE 子句中指定的顺序计算不带子查询的谓词。

CURSOR_SHARING_EXACT:Oracle 服务器可以用绑定变量替换 SQL 语句中的文字(如果这样做是安全的)。此操作是由 CURSOR_SHARING 启动参数控制的。CURSOR_SHARING_EXACT 提示HINT可禁用此行为。换句话说,Oracle 服务器执行 SQL 语句时将不尝试用绑定变量替换文字。

CACHE:CACHE 提示HINT指示优化程序在执行全表扫描时将为表检索的块放在缓冲区高速缓存的相应热部分中。此提示HINT对于小型查找表很有用。

如 V$SYSSTAT 数据字典视图中所示,CACHE 和 NOCACHE 提示HINT会影响系统统计信息表扫描(长表)和表扫描(短表)。

PUSH_PRED:PUSH_PRED 提示HINT指示优化程序将联接谓词推到视图中。

PUSH_SUBQ:PUSH_SUBQ 提示HINT指示优化程序在执行计划中尽可能早地计算未合并的子查询。如果按常规,在执行计划中最后才会执行未合并的子查询。如果执行子查询的成本相对便宜,并且可以显著减少行的数量,则较早计算子查询可以改善性能。如果子查询应用于远程表,或应用于使用合并联接联接的表,则此提示HINT不会产生任何影响。

DYNAMIC_SAMPLING:DYNAMIC_SAMPLING 提示HINT使您可以通过确定更准确的选择性和基数估计值来控制动态采样,从而改善服务器性能。可以将 DYNAMIC_SAMPLING 的值设置为 0 到 10 之间的值。级别越高,编译人员对动态采样施加的影响越大,应用的范围越广。采样默认使用游标级别,除非您指定了一个表。

请看以下示例:

SELECT /*+ dynamic_sampling(1) */ * FROM …

如果满足所有下列条件,此示例将启用动态采样:

  • 查询中有多个表。
  • 至少一个表未被分析,且没有索引。
  • 优化程序确定需要对尚未进行分析的表执行一个成本相对较高的表扫描。

 

其它提示HINT

MONITOR 强制实施实时查询监控
NO_MONITOR 禁用实时查询监控
RESULT_CACHE 高速缓存查询或查询片段的结果
NO_RESULT_CACHE 为查询或查询片断禁用结果高速
缓存
OPT_PARAM 针对查询持续时间设置初始化参数

 

MONITOR:MONITOR 提示HINT为查询强制实施实时 SQL 监控,即使语句不是长时间运行的。只有在 CONTROL_MANAGEMENT_PACK_ACCESS 参数设置为 DIAGNOSTIC+TUNING 时,此提示HINT才有效。

NO_MONITOR:NO_MONITOR 提示HINT为查询禁用实时 SQL 监控。

RESULT_CACHE:RESULT_CACHE 提示HINT指示数据库将当前查询或查询片断的结果高速缓存在内存中,然后在今后执行查询或查询片断时使用已缓存的结果。

NO_RESULT_CACHE:如果将 RESULT_CACHE_MODE 初始化参数设置为 FORCE,则优化程序会将查询结果高速缓存在结果高速缓存中。在这种情况下,NO_RESULT_CACHE 提示HINT会为当前查询禁用此类高速缓存。

OPT_PARAM:OPT_PARAM 提示HINT使您可以仅针对当前查询的持续时间设置初始化参数。此提示HINT仅对以下参数有效:OPTIMIZER_DYNAMIC_SAMPLING、OPTIMIZER_INDEX_CACHING、OPTIMIZER_INDEX_COST_ADJ、OPTIMIZER_SECURE_VIEW_MERGING 和 STAR_TRANSFORMATION_ENABLED

 

提示HINT和视图

  • 不要使用视图中的提示HINT。
  • 使用视图优化技术:

–语句转换

–像访问表一样访问结果

  • 可以使用关于可合并视图和不可合并视图的提示HINT。

由于可以在一个上下文中定义视图,然后将其用于其它上下文中,因此不应使用视图中的提示HINT或使用关于视图的提示HINT;这样的提示HINT可能会导致意外的计划。尤其要注意的是,根据视图是否可合并到顶层查询中,视图中的提示HINT的处理方式不同于关于视图的提示HINT的处理
方式。

视图优化

该语句通常会转换成访问视图基表的等效语句。优化程序可以使用下列技术之一转换语句:

  • 将视图的查询合并到访问语句中的引用查询块中。
  • 将引用查询块的谓词推到视图中。

当上述转换不可能发生时,将执行视图的查询,并像访问表一样访问结果。这发生在执行计划的 VIEW 步骤。

 

可合并视图

如果视图定义不包含以下项,则优化程序可以将视图合并到引用查询块中:

  • 集合运算符(UNION、UNION ALL、INTERSECT、MINUS)
  • CONNECT BY 子句
  • ROWNUM 伪列
  • 在选择列表中有组函数(AVG、COUNT、MAX、MIN、SUM)

提示HINT和可合并视图

优化方法和目标提示HINT可能出现在顶层查询或视图中:

  • 如果顶层查询中存在这样的提示HINT,则不管视图中是否包含此类提示HINT,都使用此提示HINT。
  • 如果没有顶层优化程序模式提示HINT,只要视图中的所有模式提示HINT是一致的,就使用被引用视图中的模式提示HINT。
  • 如果被引用视图中有两个或多个模式提示HINT相互冲突,则放弃视图中的所有模式提示HINT,而使用默认的或用户指定的会话模式。

关于被引用视图的访问方法提示HINT和联接提示HINT将被忽略,除非视图只包含一个表(或引用只包含一个表的另一视图)。对于这样的单表视图,关于视图的访问方法提示HINT或联接提示HINT将应用于视图中的表。

访问方法提示HINT和联接提示HINT也可能出现在视图定义中:

  • 如果视图是子查询(即,如果视图出现在 SELECT 语句的 FROM 子句中),则当视图与顶层查询合并时将保留视图中的所有访问方法提示HINT和联接提示HINT。
  • 如果视图不是子查询,则仅当顶层查询没有引用其它表或视图时(即,如果 SELECT 语句的 FROM 子句仅包含此视图),才会保留视图中的访问方法提示HINT和联接提示HINT。

提示HINT和不可合并视图

使用不可合并视图时,视图中的优化程序模式提示HINT将被忽略。由顶层查询来决定优化模式。

由于不可合并视图是独立于顶层查询单独进行优化的,因此视图中的访问方法提示HINT和联接提示HINT总是被保留。出于同样的原因,顶层查询中关于视图的访问方法提示HINT将被忽略。

但是,由于(在这种情况下)不可合并视图与表类似,因此会保留顶层查询中关于视图的联接提示HINT。

 

全局表提示HINT

  • 扩展的提示HINT语法使您可以为出现在视图中的表指定提示HINT
  • 使用递归点表示法在提示HINT中引用表名称

CREATE view city_view AS

SELECT *

FROM   customers c

WHERE  cust_city like ‘S%’;

 

SELECT /*+ index(v.c cust_credit_limit_idx) */

    v.cust_last_name, v.cust_credit_limit

FROM   city_view v

WHERE  cust_credit_limit > 5000;

 

常规情况下,指定了表的提示HINT引用此提示HINT所在的 DELETE、SELECT 或 UPDATE 查询块中的表,而不是语句所引用的视图内的表。如果需要为视图内的表指定提示HINT,建议您使用全局提示HINT,而不要将提示HINT嵌入到视图中。

如幻灯片所示,通过使用扩展的表指定语法(该语法包括视图名称和表名称),可将表提示HINT转换成全局提示HINT。另外,在指定表之前还可以选择指定一个查询块名称。

例如,通过使用全局提示HINT结构,就不需要在视图主体中指定索引提示HINT,从而避免修改视图。

注:如果全局提示HINT引用了在同一查询中使用了两次的表名称或别名(例如,在 UNION 语句中),则提示HINT仅应用于表(或别名)的第一个实例。

 

 

在提示HINT中指定一个查询块

explain plan for

select /*+ FULL(@strange dept) */ ename

from emp e, (select /*+ QB_NAME(strange) */ * 

             from dept where deptno=10) d

where e.deptno = d.deptno and d.loc = ‘C’;

 

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, NULL, ‘ALL’));

 

Plan hash value: 615168685

—————————————————————
| Id  | Operation          | Name | Rows  | Bytes | Cost(%CPU)|

—————————————————————
|   0 | SELECT STATEMENT   |      |     1 |    41 |     7 (15)|

|*  1 |  HASH JOIN         |      |     1 |    41 |     7 (15)|

|*  2 |   TABLE ACCESS FULL| DEPT |     1 |    21 |     3  (0)|
|*  3 |   TABLE ACCESS FULL| EMP  |     3 |    60 |     3  (0)|
—————————————————————

Query Block Name / Object Alias (identified by operation id):

————————————————————-

   1 – SEL$DB579D14

   2 – SEL$DB579D14 / DEPT@STRANGE

   3 – SEL$DB579D14 / E@SEL$1

 

在许多提示HINT中都可以指定一个可选的查询块名称,以指定提示HINT所应用于的查询块。此语法使您可以在外层查询中指定一个应用于内嵌视图的提示HINT。

查询块变量的语法采用 @queryblock 形式,其中 queryblock 是一个标识符,用于指定查询中的一个查询块。queryblock 标识符可以是系统生成的,也可以是用户指定的。在查询块自身中指定一个提示HINT,也可以将提示HINT应用于该查询块,并不一定要指定 @queryblock 语法。

幻灯片给出了一个示例。可以看到 SELECT 语句使用了一个内嵌视图。通过使用 QB_NAME 提示HINT,为相应查询块指定名称 strange。

本示例假设,DEPT 表的 DEPTNO 列有一个索引,这样优化程序通常可以选择该索引来访问 DEPT 表。不过,由于您指定 FULL 提示HINT应用于主查询块中的 strange 查询块,所以优化程序不使用上述索引。可以看到执行计划显示出对 DEPT 表执行了一个全表扫描。另外,计划的输出还清楚显示了原始查询中的各个查询块的系统生成名称。

 

指定完整的提示HINT集

SELECT /*+ LEADING(e2 e1) USE_NL(e1)
   INDEX(e1 emp_emp_id_pk) USE_MERGE(j) FULL(j) */

    e1.first_name, e1.last_name, j.job_id,
     sum(e2.salary) total_sal

FROM hr.employees e1, hr.employees e2, hr.job_history j

WHERE e1.employee_id = e2.manager_id

AND e1.employee_id = j.employee_id

AND e1.hire_date = j.start_date

GROUP BY e1.first_name, e1.last_name, j.job_id

ORDER BY total_sal;

 

使用提示HINT时,您有时可能需要指定一个完整的提示HINT集,以保证使用最佳执行计划。例如,如果您有一个包含许多表联接的非常复杂的查询,并且,如果您仅为给定表指定 INDEX 提示HINT,则优化程序需要自己确定要使用的访问路径以及相应的联接方法等等。因此,即使您给出 INDEX 提示HINT,优化程序也不一定使用该提示HINT,因为优化程序可能已确定它选定的联接方法和访问路径不能使用请求的索引。

在本例中,LEADING 提示HINT指定了要使用的确切联接顺序。同时还指定了对不同的表要使用的联接方法。

 

 

如何验证SQL PROFILE的性能?

如何检验sql profile的性能

10g以后的sql tuning advisor(可以通过Enterprise Manager或DBMS_SQLTUNE包访问)会给出对于SQL的建议包括以下四种:

1. 收集最新的统计信息
2. 彻底重构该SQL语句
3. 创建推荐的索引
4. 启用SQL TUNING ADVISOR找到的SQL PROFILE

这里我们要注意的是在production环境中显然不可能让我们在没有充分测试的前提下随意为SQL接受一个PROFILE,因为这可能为本来就性能糟糕而需要调优的系统引来变化。 但是如果恰巧没有合适的TEST环境,而你的SQL PROFILE又可能是性能压力的救命稻草时,我们可以使用以下方法在production环境中局部测试SQL PROFILE,仅在session级别生效:

 

 

Oracle Database 12c Enterprise Edition Release 12.1.0.0.2 - 64bit Beta
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create table profile_test tablespace users as select * from dba_objects;

Table created.

SQL> create index ix_objd on profile_test(object_id);

Index created.

SQL> set linesize 200 pagesize 2000
SQL>  exec dbms_stats.gather_table_stats('','PROFILE_TEST');

PL/SQL procedure successfully completed.

SQL> set autotrace traceonly;

SQL>  select /*+ FULL( profile_test) */ * from profile_test where object_id=5060;

Execution Plan
----------------------------------------------------------
Plan hash value: 663678050

----------------------------------------------------------------------------------
| Id  | Operation         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |              |     1 |   113 |   408   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| PROFILE_TEST |     1 |   113 |   408   (1)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJECT_ID"=5060)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1471  consistent gets
          0  physical reads
          0  redo size
       1779  bytes sent via SQL*Net to client
        543  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

		  f3v7dxj4bggvq

Tune the sql
~~~~~~~~~~~~

GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : TASK_226
Tuning Task Owner  : SYS
Workload Type      : Single SQL Statement
Scope              : COMPREHENSIVE
Time Limit(seconds): 1800
Completion Status  : COMPLETED
Started at         : 11/30/2012 13:13:27
Completed at       : 11/30/2012 13:13:30

-------------------------------------------------------------------------------
Schema Name   : SYS
Container Name: CDB$ROOT
SQL ID        : f3v7dxj4bggvq
SQL Text      :  select /*+ FULL( profile_test) */ * from profile_test where
                object_id=5060

-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------

1- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------
  A potentially better execution plan was found for this statement.

  Recommendation (estimated benefit: 99.79%)
  ------------------------------------------
  - Consider accepting the recommended SQL profile.
    execute dbms_sqltune.accept_sql_profile(task_name => 'TASK_226',
            task_owner => 'SYS', replace => TRUE);

  Validation results
  ------------------
  The SQL profile was tested by executing both its plan and the original plan
  and measuring their respective execution statistics. A plan may have been
  only partially executed if the other could be run to completion in less time.

                           Original Plan  With SQL Profile  % Improved
                           -------------  ----------------  ----------
  Completion Status:            COMPLETE          COMPLETE
  Elapsed Time (s):             .005407           .000034      99.37 %
  CPU Time (s):                 .004599                 0        100 %
  User I/O Time (s):                  0                 0
  Buffer Gets:                     1470                 3      99.79 %
  Physical Read Requests:             0                 0
  Physical Write Requests:            0                 0
  Physical Read Bytes:                0                 0
  Physical Write Bytes:               0                 0
  Rows Processed:                     1                 1
  Fetches:                            1                 1
  Executions:                         1                 1

  Notes
  -----
  1. Statistics for the original plan were averaged over 10 executions.
  2. Statistics for the SQL profile plan were averaged over 10 executions.

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original With Adjusted Cost
------------------------------
Plan hash value: 663678050

----------------------------------------------------------------------------------
| Id  | Operation         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |              |     1 |   113 |   408   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| PROFILE_TEST |     1 |   113 |   408   (1)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJECT_ID"=5060)

2- Using SQL Profile
--------------------
Plan hash value: 2974300728

----------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |              |     1 |   113 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| PROFILE_TEST |     1 |   113 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IX_OBJD      |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=5060)

-------------------------------------------------------------------------------

    execute dbms_sqltune.accept_sql_profile(task_name => 'TASK_226',task_owner => 'SYS', replace => TRUE,category=>'MACLEAN_TEST');		  

SQL> set autotrace on;
SQL> select /*+ FULL( profile_test) */ * from profile_test where
  2                  object_id=5060;

1 row selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 2974300728

----------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |              |     1 |   113 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| PROFILE_TEST |     1 |   113 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IX_OBJD      |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=5060)

Note
-----
   - SQL profile "SYS_SQLPROF_013b5177cf260000" used for this statement

Statistics
----------------------------------------------------------
        275  recursive calls
          0  db block gets
        130  consistent gets
          1  physical reads
          0  redo size
       1783  bytes sent via SQL*Net to client
        543  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         27  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> 
SQL> alter session set sqltune_category=DEFAULT;

Session altered.

SQL> select /*+ FULL( profile_test) */ * from profile_test where object_id=5060;

1 row selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 663678050

----------------------------------------------------------------------------------
| Id  | Operation         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |              |     1 |   113 |   408   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| PROFILE_TEST |     1 |   113 |   408   (1)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJECT_ID"=5060)

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       1471  consistent gets
          0  physical reads
          0  redo size
       1779  bytes sent via SQL*Net to client
        543  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

 

 

以上我们通过sqltune_category将SQL PROFILE的作用域限定在session级别,实现了对SQL PROFILE的性能测试。

Oracle SQL Optimizer IN VS Exists Again

传统的SQL优化思想认为IN、Exists这2种写法不同数据量的环境中各擅胜场,Developer应当根据实际情况合理运用IN或Exists。

实际我认为,这种认识对于现代SQL优化器Optimizer(10g以后)不再适用。 CBO优化器中本身包含了查询转换(Query Transformation)的功能。

为什么CBO要做查询转换(Query Transformation)?

回答: 用户提交给SQL引擎的语句可能不是执行查询最有效的语句

查询转换(Query Transformation)做了什么?

回答: 查询转换按照固定的语法将语句重写为等意的SQL,但是优化了其SQL结构

查询转换(Query Transformation)包括启发式地查询转换和基于成本的查询转换。

对于IN、Exists , CBO optimizer 的查询装换效果如何?:

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for 64-bit Windows: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

SQL> select count(1) from joinA A where A.CUST_ID in ( select B.cust_id from joinb  B where B.CUST_FIRST_NAME like 'C%');

  COUNT(1)
----------
     39381

SQL> alter system flush shared_pool;

System altered.

SQL> alter system flush shared_pool;

System altered.

SQL> alter session set events '10053 trace name context forever,level 1';

Session altered.

SQL> select count(1) from joinA A where A.CUST_ID in ( select B.cust_id from joinb  B where B.CUST_FIRST_NAME like 'C%');

  COUNT(1)
----------
     39381

SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name
D:\APP\ML\diag\rdbms\testem\testem\trace\testem_ora_6776.trc

Final query after transformations:******* UNPARSED QUERY IS *******
SELECT COUNT(*) "COUNT(1)"
  FROM (SELECT "B"."CUST_ID" "CUST_ID"
          FROM "SYS"."JOINB" "B"
         WHERE "B"."CUST_FIRST_NAME" LIKE 'C%') "VW_NSO_1",
       "SYS"."JOINA" "A"
 WHERE "A"."CUST_ID" = "VW_NSO_1"."CUST_ID"

kkoqbc: optimizing query block SEL$683B0107 (#2)

SQL> alter session set events '10053 trace name context forever,level 1';

Session altered.

SQL> select count(1) from joinA A where exists ( select 1  from joinb  B where B.CUST_FIRST_NAME like 'C%' and B.cust_id=A.cust_id  );

  COUNT(1)
----------
     39381

Final query after transformations:******* UNPARSED QUERY IS *******

SELECT COUNT(*) "COUNT(1)"
  FROM (SELECT "B"."CUST_ID" "ITEM_1"
          FROM "SYS"."JOINB" "B"
         WHERE "B"."CUST_FIRST_NAME" LIKE 'C%') "VW_SQ_1",
       "SYS"."JOINA" "A"
 WHERE "VW_SQ_1"."ITEM_1" = "A"."CUST_ID"

 

 

 

如以上10053 trace 所显示 对于2个分别使用了IN和Exists的查询, CBO Optimizer查询转换后得到的结果十分类似:

IN:
SELECT COUNT(*) “COUNT(1)”
FROM (SELECT “B”.”CUST_ID” “CUST_ID”
FROM “SYS”.”JOINB” “B”
WHERE “B”.”CUST_FIRST_NAME” LIKE ‘C%’) “VW_NSO_1”,
“SYS”.”JOINA” “A”
WHERE “A”.”CUST_ID” = “VW_NSO_1″.”CUST_ID”

Exists:

SELECT COUNT(*) “COUNT(1)”
FROM (SELECT “B”.”CUST_ID” “ITEM_1”
FROM “SYS”.”JOINB” “B”
WHERE “B”.”CUST_FIRST_NAME” LIKE ‘C%’) “VW_SQ_1”,
“SYS”.”JOINA” “A”
WHERE “VW_SQ_1”.”ITEM_1″ = “A”.”CUST_ID”

CBO在完成Query transformations之后才会对转换后的语句进行APA(access path analysis)和后续的优化树构建、成本比较等等,一般来说如果你使用10g以后的CBO ,可以认为语义等价的IN或Exists在性能上也不会有太大的区别。

More About SYS_AUTO_SQL_TUNING_TASK

SELECT parameter_name, parameter_value
FROM   dba_advisor_parameters
WHERE  task_name = 'SYS_AUTO_SQL_TUNING_TASK'

PARAMETER_NAME                 PARAMETER_VALUE
------------------------------ --------------------------------------------------
USERNAME                       UNUSED
BASIC_FILTER                   UNUSED
PLAN_FILTER                    UNUSED
RANK_MEASURE1                  UNUSED
RANK_MEASURE2                  UNUSED
RANK_MEASURE3                  UNUSED
SQL_PERCENTAGE                 1
SQL_LIMIT                      -1
RESUME_FILTER                  UNUSED
LOCAL_TIME_LIMIT               1200
TEST_EXECUTE                   FULL
APPLY_CAPTURED_COMPILENV       UNUSED
ACCEPT_SQL_PROFILES            FALSE
MAX_SQL_PROFILES_PER_EXEC      20
MAX_AUTO_SQL_PROFILES          10000
DAYS_TO_EXPIRE                 UNLIMITED
END_SNAPSHOT                   UNUSED
END_TIME                       UNUSED
INSTANCE                       UNUSED
JOURNALING                     INFORMATION
MODE                           COMPREHENSIVE
START_SNAPSHOT                 UNUSED
START_TIME                     UNUSED
TARGET_OBJECTS                 1
TIME_LIMIT                     3600
DEFAULT_EXECUTION_TYPE         TUNE SQL
ORA_EM_PARAM1                  UNUSED
ORA_EM_PARAM2                  UNUSED
ORA_EM_PARAM3                  UNUSED
ORA_EM_PARAM4                  UNUSED
ORA_EM_PARAM5                  UNUSED
ORA_EM_PARAM6                  UNUSED
ORA_EM_PARAM7                  UNUSED
ORA_EM_PARAM8                  UNUSED
ORA_EM_PARAM9                  UNUSED
ORA_EM_PARAM10                 UNUSED
EXECUTION_DAYS_TO_EXPIRE       30

SQL> select execution_name,status,execution_start,execution_end from dba_advisor_executions where task_name='SYS_AUTO_SQL_TUNING_TASK';

EXECUTION_NAME                 STATUS      EXECUTION EXECUTION
------------------------------ ----------- --------- ---------
EXEC_112                       COMPLETED   02-JUN-13 02-JUN-13
EXEC_153                       COMPLETED   03-JUN-13 03-JUN-13
EXEC_178                       COMPLETED   04-JUN-13 04-JUN-13
EXEC_203                       COMPLETED   05-JUN-13 05-JUN-13
EXEC_228                       COMPLETED   06-JUN-13 06-JUN-13
EXEC_254                       COMPLETED   07-JUN-13 07-JUN-13
EXEC_263                       COMPLETED   08-JUN-13 08-JUN-13
EXEC_297                       COMPLETED   29-JUN-13 29-JUN-13
EXEC_318                       COMPLETED   30-JUN-13 30-JUN-13
EXEC_319                       COMPLETED   30-JUN-13 30-JUN-13
EXEC_320                       COMPLETED   30-JUN-13 30-JUN-13
EXEC_321                       COMPLETED   30-JUN-13 30-JUN-13
EXEC_78                        COMPLETED   31-MAY-13 31-MAY-13
EXEC_88                        COMPLETED   01-JUN-13 01-JUN-13

14 rows selected.

From the call stack
kesutl_prs_idn()
keshs_parse_profile_name()
qsmoAlterPlans()
kkopmCheckSmbUpdate

DBA_ADVISOR_EXECUTIONS:获取有关各个任务执行的数据 
DBA_ADVISOR_SQLSTATS:查看在测试 SQL 概要文件时生成的测试 - 执行统计信息 
DBA_ADVISOR_SQLPLANS:查看在测试 - 执行过程中遇到的计划

Bulk Collect/FORALL的性能测试

有同学在T.askmac.cn上提问关于bulk  collect /FORALL对性能的影响, 提问的内容是针对 bulk collect后FORALL批量INSERT 和 直接使用SQL语句INSERT SELECT间的对比。

 

AS maclean Answered:

1.

bulk collect 主要用在批量 填充 队列变量,这些array/table 变量可能最后用于打印数据,对于INSERT 一般建议直接用SQL加上nologging +append 优化

例如:
Cur_Num number := DBMS_Sql.Open_Cursor();
rc Sys_Refcursor;

cursor e is select Employee_ID, First_Name, Last_Name
from Employees;
type Emps_t is table of e%rowtype;
Emps Emps_t;
begin
DBMS_Sql.Parse(
c=>Cur_Num, Language_Flag=>DBMS_Sql.Native, Statement=>
‘select Employee_ID, First_Name, Last_Name
from Employees
where Department_ID = :d and Salary > :s and …’);

DBMS_Sql.Bind_Variable(Cur_Num, ‘:d’, Department_ID);
DBMS_Sql.Bind_Variable(Cur_Num, ‘:s’, Salary);

Dummy := DBMS_Sql.Execute(Cur_Num);
— Switch to ref cursor and native dynamic SQL
rc := DBMS_Sql.To_Refcursor(Cur_Num);

  fetch rc bulk collect into Emps;
  close rc;

以上利用  bulk collect 批量填充了Emps这张PL/SQL 表,之后会将Emps输出到终端

2.

An ORA-22813 when using BULK COLLECT is typically expected behavior indicating that you have exceeded the amount of free memory in the PGA.  As collections are processed by PL/SQL they use the PGA to store their memory structures.  Depending on the LIMIT size of the BULK COLLECT and additional processing of the collected data you may exceed the free memory of the PGA.  While intuitively you may think that increasing the PGA memory and increasing the LIMIT size will increase performance, the following example shows you that this is not true in this case.  So, by reviewing this example you should be able to strike a balance between a reasonable LIMIT size and the size of the PGA while maintaining a high level of performance using BULK COLLECT.

 

合理设置limit size确实可以 避免PGA overflow  避免出现ORA-22813 错误

 

[oracle@vrh8 ~]$ oerr ora 22813
22813, 00000, “operand value exceeds system limits”
// *Cause:  Object or Collection value was too large. The size of the value
//          might have exceeded 30k in a SORT context, or the size might be
//          too big for available memory.
// *Action:  Choose another value and retry the operation.

 

 

这里我们姑且不谈bulk collect/forall 和直接使用SQL  INSERT ..SELECT间的性能对比,而来看看 bulk collect/forall 与 普通的 fetch 、FOR LOOP的性能对比

 

 

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE    10.2.0.5.0      Production
TNS for Linux: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - Production

SQL> 
SQL> 
SQL> select * from global_name;

GLOBAL_NAME
--------------------------------------------------------------------------------
www.askmac.cn

SQL> create table maclean_forall tablespace users as select * from dba_objects;

Table created.

SQL> create table maclean_forall2 tablespace users as select * from dba_objects where rownum=0;

Table created.

INSERT DATA:

SQL> select count(*) from maclean_forall;

  COUNT(*)
----------
    815200

SQL> select count(*) from maclean_forall2;

  COUNT(*)
----------
         0

SQL> alter table maclean_forall nologging;

Table altered.

SQL> alter table maclean_forall2 nologging;

Table altered.

SQL> set timing on;
SQL> select  st.name,ss.value from v$mystat ss, v$statname st 
  2  where ss.statistic# = st.statistic#                 
  3  and st.name in ('redo size','undo change vector size','CPU used by this session');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
CPU used by this session                                                  1
redo size                                                                 0
undo change vector size                                                   0

Elapsed: 00:00:00.00
SQL> 
SQL> 

SQL> oradebug setmypid;
Statement processed.
SQL> oradebug event 10046 trace name context forever,level 8;
Statement processed.
SQL> 
SQL> declare
  2     type recstartyp is table of maclean_forall%rowtype index by BINARY_INTEGER;
  3     rec_tab recstartyp;
  4     cursor temp is select * from maclean_forall;
  5  begin
  6     open temp;
  7     fetch temp bulk collect into rec_tab;
  8     FORALL i in rec_tab.first..rec_tab.last
  9        insert /*+ append */  into maclean_forall2 values rec_tab(i);
 10     commit;
 11     close temp;
 12  end;
 13  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:10.00
SQL> 
SQL> oradebug event 10046 trace name context off;
Statement processed.
SQL> oradebug tracefile_name
/s01/admin/G10R25/udump/g10r25_ora_24477.trc
SQL> 
SQL> select  st.name,ss.value from v$mystat ss, v$statname st 
  2  where ss.statistic# = st.statistic#                 
  3  and st.name in ('redo size','undo change vector size','CPU used by this session');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
CPU used by this session                                                436
redo size                                                          91943804
undo change vector size                                             3572052

Elapsed: 00:00:00.01

SELECT *
FROM
 MACLEAN_FORALL

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          1          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      2.05       2.01       7275      11266          0      815200
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      2.06       2.01       7275      11267          0      815200

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS   (recursive depth: 1)

Rows     Row Source Operation
-------  ---------------------------------------------------
 815200  TABLE ACCESS FULL MACLEAN_FORALL (cr=11266 pr=7275 pw=0 time=14673632 us)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file scattered read                        512        0.00          0.03
  db file sequential read                         3        0.00          0.00
********************************************************************************

INSERT /*+ append */ INTO MACLEAN_FORALL2
VALUES
 (:B1 ,:B2 ,:B3 ,:B4 ,:B5 ,:B6 ,:B7 ,:B8 ,:B9 ,:B10 ,:B11 ,:B12 ,:B13 )

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      2.17       7.57      11805      22071     113084      815200
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      2.17       7.57      11805      22071     113084      815200

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS   (recursive depth: 1)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                     11805        0.01          0.19
  log file switch completion                      2        0.64          1.04
  log file switch (checkpoint incomplete)         9        0.97          2.95
  flashback buf free by RVWR                      6        0.10          0.15
  latch: cache buffers lru chain                  2        0.00          0.00

 解析1次 执行1次   cpu time= 2.06 +  2.17=4.23s 
 redo size 91943804    87MB          undo 3572052

elapsed time= 7.57+ 2.01=9.58s 

SQL> select  st.name,ss.value from v$mystat ss, v$statname st 
  2  where ss.statistic# = st.statistic#                 
  3  and st.name in ('redo size','undo change vector size','CPU used by this session');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
CPU used by this session                                                  0
redo size                                                                 0
undo change vector size                                                   0

SQL> oradebug setmypid;
Statement processed.
SQL> oradebug event 10046 trace name context forever,level 8;
Statement processed.
SQL> 
SQL> set timing on;
SQL> 
SQL> 
SQL> 
SQL> declare
  2     type recstartyp is table of maclean_forall%rowtype index by BINARY_INTEGER;
  3     rec_tab recstartyp;
  4     cursor temp is select * from maclean_forall;
  5  begin
  6     open temp;
  7     fetch temp bulk collect into rec_tab;
  8     FORALL i in rec_tab.first..rec_tab.last
  9        insert  into maclean_forall2 values rec_tab(i);
 10     commit;
 11     close temp;
 12  end;
 13  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:09.34
SQL> 
SQL> oradebug event 10046 trace name context off;
Statement processed.
SQL> oradebug tracefile_name
/s01/admin/G10R25/udump/g10r25_ora_24609.trc
SQL> 
SQL> 
SQL> select  st.name,ss.value from v$mystat ss, v$statname st 
  2  where ss.statistic# = st.statistic#                 
  3  and st.name in ('redo size','undo change vector size','CPU used by this session');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
CPU used by this session                                                455
redo size                                                          91679440
undo change vector size                                             3518580

Elapsed: 00:00:00.00

declare
   type recstartyp is table of maclean_forall%rowtype index by BINARY_INTEGER;
   rec_tab recstartyp;
   cursor temp is select * from maclean_forall;
begin
   open temp;
   fetch temp bulk collect into rec_tab;
   FORALL i in rec_tab.first..rec_tab.last
      insert  into maclean_forall2 values rec_tab(i);
   commit;
   close temp;
end;

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.04       0.04          0      32975     108697           1
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.05       0.05          0      32975     108697           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

SELECT *
FROM
 MACLEAN_FORALL

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      1.98       1.94       5629      11270          0      815200
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      1.98       1.94       5629      11270          0      815200

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: SYS   (recursive depth: 1)

Rows     Row Source Operation
-------  ---------------------------------------------------
 815200  TABLE ACCESS FULL MACLEAN_FORALL (cr=11270 pr=5629 pw=0 time=15488945 us)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                         7        0.00          0.00
  db file scattered read                        356        0.00          0.01
********************************************************************************

INSERT INTO MACLEAN_FORALL2
VALUES
 (:B1 ,:B2 ,:B3 ,:B4 ,:B5 ,:B6 ,:B7 ,:B8 ,:B9 ,:B10 ,:B11 ,:B12 ,:B13 )

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      2.43       7.07      11328      21705     108696      815200
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      2.44       7.07      11328      21705     108696      815200

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS   (recursive depth: 1)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  log file switch completion                      4        0.40          0.41
  db file sequential read                     11328        0.41          3.91
  latch: cache buffers lru chain                  5        0.00          0.00
  log file switch (checkpoint incomplete)         3        0.00          0.00

解析1次 执行1次!

cpu time= 2.43 +  1.98 =4.41 s 

redo size  91679440   undo change vector size   3518580

elapsed = 7.07 + 1.94= 9.01

在以上测试中 PL/SQL部分仅占用 0.05 s的CPU TIME 

SQL>  set timing on;
SQL> select  st.name,ss.value from v$mystat ss, v$statname st 
  2  where ss.statistic# = st.statistic#                 
  3  and st.name in ('redo size','undo change vector size','CPU used by this session');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
CPU used by this session                                                  1
redo size                                                                 0
undo change vector size                                                   0

Elapsed: 00:00:00.01
SQL> 
SQL> 
SQL> 
SQL> oradebug setmypid;
Statement processed.
SQL> oradebug event 10046 trace name context forever,level 8;
Statement processed.
SQL> 
SQL> 
SQL> declare
  2  
  3     cursor temp is select * from maclean_forall;
  4  begin
  5  
  6    for i in temp loop
  7    insert into maclean_forall2 values i;
  8    end loop;
  9    commit;
 10  end;
 11  /

PL/SQL procedure successfully completed.

Elapsed: 00:01:07.18
SQL> 
SQL> 
SQL> 
SQL> oradebug event 10046 trace name context off;
Statement processed.
SQL> oradebug tracefile_name
/s01/admin/G10R25/udump/g10r25_ora_24804.trc
SQL> 
SQL> select  st.name,ss.value from v$mystat ss, v$statname st 
  2  where ss.statistic# = st.statistic#                 
  3  and st.name in ('redo size','undo change vector size','CPU used by this session');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
CPU used by this session                                               5599
redo size                                                         318363048
undo change vector size                                            74972216

Elapsed: 00:00:00.00

declare
   cursor temp is select * from maclean_forall;
begin
  for i in temp loop
  insert into maclean_forall2 values i;
  end loop;
  commit;
end;

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1     44.79      31.48      31534      32491     940113           1
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2     44.80      31.49      31534      32491     940113           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  log file sync                                   1        0.00          0.00
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        4.83          4.83

SELECT *
FROM
 MACLEAN_FORALL

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch     8153      1.02       1.57      10499      19310          0      815200
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total     8155      1.02       1.57      10499      19310          0      815200

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: SYS   (recursive depth: 1)

Rows     Row Source Operation
-------  ---------------------------------------------------
 815200  TABLE ACCESS FULL MACLEAN_FORALL (cr=19310 pr=10499 pw=0 time=6523808 us)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file scattered read                        667        0.00          0.03
********************************************************************************

INSERT INTO MACLEAN_FORALL2
VALUES
 (:B1 ,:B2 ,:B3 ,:B4 ,:B5 ,:B6 ,:B7 ,:B8 ,:B9 ,:B10 ,:B11 ,:B12 ,:B13 )

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute 815200     10.10      32.48      21035      13181     940112      815200
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total   815201     10.10      32.48      21035      13181     940112      815200

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS   (recursive depth: 1)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                     21034        0.63          3.25
  log file switch completion                      9        0.93          2.06
  log file switch (checkpoint incomplete)        18        0.97          4.92
  latch: library cache lock                       1        0.00          0.00
********************************************************************************


游标查询 MACLEAN_FORALL  执行一次 但fetch了 8153次, insert共执行了 815200次 , 
最离谱的是Pl/SQL 引擎和SQL引擎之间的切换大约消耗了30s 


cpu time = 32.48+ 1.57 + 31.48 = 65s 
redo size= 318363048 bytes = 303 MB

 

 

就以上测试可以得出以上结论:

1. FORALL执行使用 原本需要大量循环完成的工作在一次Execute内完成,节省了大量的CPU TIME(大约78%)。
2. append对 forall INSERT起不到减少redo的作用,但是FORALL INSERT本身对比普通loop insert节省了大量redo (大约71%) 和 大量的undo (大约95%)的undo
3. 使用FOR ALL的代价是消耗大量的PGA内存
4. 大量循环LOOP,从Pl/SQL引擎到SQL引擎的切换的消耗是巨大的,几乎占用了以上测试中50%的CPU TIME , 而FOR ALL/Bulk collect恰恰可以避免这种切换。

 

PS: 直接使用INSERT /*+ APPEND */ INTO SELECT的性能测试:

 

 

SQL> set timing on;
SQL> select  st.name,ss.value from v$mystat ss, v$statname st 
  2  where ss.statistic# = st.statistic#                 
  3  and st.name in ('redo size','undo change vector size','CPU used by this session');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
CPU used by this session                                                  1
redo size                                                                 0
undo change vector size                                                   0

Elapsed: 00:00:00.00
SQL> oradebug setmypid;
Statement processed.
SQL> oradebug event 10046 trace name context forever,level 8;
Statement processed.
SQL> 
SQL> insert /*+ append */  into maclean_forall2 select * from maclean_forall;

815200 rows created.

Elapsed: 00:00:02.27
SQL> oradebug event 10046 trace name context off;
Statement processed.
SQL> oradebug tracefile_name
/s01/admin/G10R25/udump/g10r25_ora_25621.trc
SQL> 
SQL> 
SQL> select  st.name,ss.value from v$mystat ss, v$statname st 
  2  where ss.statistic# = st.statistic#                 
  3  and st.name in ('redo size','undo change vector size','CPU used by this session');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
CPU used by this session                                                103
redo size                                                            260168
undo change vector size                                               57544

insert /*+ append */  into maclean_forall2 select * from maclean_forall

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          1          0           0
Execute      1      0.99       2.18      21619      12238      13865      815200
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      1.00       2.19      21619      12239      13865      815200

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Rows     Row Source Operation
-------  ---------------------------------------------------
      1  LOAD AS SELECT  (cr=12238 pr=21619 pw=11206 time=2187590 us)
 815200   TABLE ACCESS FULL MACLEAN_FORALL (cr=11267 pr=10263 pw=0 time=6521656 us)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                       155        0.00          0.00
  flashback buf free by RVWR                     28        0.12          1.15
  db file scattered read                        701        0.00          0.04
  direct path write                               2        0.00          0.00
  direct path sync                                1        0.02          0.02
  control file sequential read                    8        0.00          0.00
  control file parallel write                     4        0.00          0.00
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        7.32          7.32

 

 

 

直接SQL INSERT..SELECT 的性能还是要好过bulk collect/FORALL的, 正如Tom kyte所说:”如果可能,尽量利用一条SQL语句完成工作。如果无法用一条SQL语句完成,就通过PL/SQL实现(不过,尽可能少用PL/SQL!)。如果在PL/SQL中也无法做到(因为它缺少一些特性,如列出目录中的文件),可以试试使用Java存储过程来实现。如果Java还办不到,那就C外部存储过程中实现。如果速度要求很高,或者要使用采用C编写的一个第三方API,就常常使用这种方法。如果在C外部例程中还无法实现,你就该好好想想有没有必要做这个工作了。”

【性能优化】PX_MISMATCH导致Oracle实例挂起

某套核心RAC库出现一个节点HANG的现象,分析AWR发现大量resmgr:cpu quantum等待事件,且parse time消耗了大量的DB TIME:

 

resmgr cpu quantum event

 

 

parse time elapsed

 

 

检查解析语句发现存在大量游标无法共享的问题,通过v$SQL_SHARED_CURSOR定位无法共享的原因,发现为PX_MISMATCH。

 

“PX_MISMATCH”意味着游标无法共享的原因是不同的并行执行力或不同的执行计划,通过内部资料找到Bug 9375300 – Cursors not shared due to reason ‘PQ_SLAVE_MISMATCH’ or ‘PX_MISMATCH’ on RAC [ID 9375300.8]。

 

对于该类 ‘PQ_SLAVE_MISMATCH’ or ‘PX_MISMATCH’引起的游标无法共享,一般建议设置parallel_degree_policy=MANUAL来避免一些可能的BUG.

 

 

另外使用11g新特性parallel_force_local=true也可能导致该PX_MISMATCH的问题。

 

如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!

 

诗檀软件专业数据库修复团队

 

服务热线 : 13764045638   QQ号:47079569    邮箱:service@parnassusdata.com

 

 

相关的一些BUG还有:

 

PX Bug 11808966 – SQL ON GV$ TABLES GENERATES MULTIPLE VERSIONS WITH REASON PX_MISMATCH
PX Bug 10235518 – HIGH VERSION COUNT FOR GV$INSTANCE DUE TO PX_MISMATCH IN RAC
PX Bug 10297948 – FREQUENT PX MISMATCHES OCCURRING FOR PARTICULAR SQL
PX Bug 11818088 – HIGH VERSION COUNT ON PX_MISMATCH AND WAIT ON CURSOR:  MUTEXS

11.2.0.1.BP08,
All active instances used in calculation of dop when
9671271 11.2.0.2.BP03, 11.2.0.3, parallel_force_local=true / High version count on
12.1.0.0
PX_MISMATCH

Richard Niemiec又一力作《Oracle Database 11g Release 2 Performance Tuning Tips & Techniques》

对Oracle数据库调优性能浓厚的朋友肯定没有错过TUSC著名的Richard Niemiec的<Oracle Database 9i/10g Performance Tuning & Tips & Techniques> ,这2本书目前有中文译版; 这2本书包含了 Richard Niemiec 丰富的Oracle Database 调优经验、详细的案例研究。 Richard Niemiec是一名世界顶尖的Oracle优化专家,同时他也是一位Oracle认证的管理大师OCM, 他的书为优化人员提供了大量的提示和技巧:

 

 

 

 

随着10g 版本正式进入Sustaining Support, 12c R1版本可能在12年末、13年初release , 现在正是 11g Release 2开始在国内大范围推广使用的时段。

 

如果你现在对 11g 的Tuning 新特性还不甚了解,包括如:adaptive Cursor Sharing、Result Cache、SQL Performance Analayze …. 。 你完全需要一本 11g 调优的完全指南,  而 Richard Niemiec 的 <Oracle Database 11g Release 2 Performance Tuning Tips & Techniques> 就是这样一本好书, 奉上封面和章节目录, 虽然这本书目前还没有中译版,但是相信很快可见:

 

 

 

 

·        Chapter 1   11g R1 & R2 New Features: Rewritten completely for basic Oracle11gR2 new features

·        Chapter 2   Basic Index Principles: Expanded to cover all of the index types and tested for 11gR2

·        Chapter 3   Disk Implementation: Updated for 11gR2: ASM, LMT, Auto UNDO, and improved I/O sections

·        Chapter 4   Initialization Parameters: Added MEMORY_TARGET and updated parameters for 11gR2

·        Chapter 5   Enterprise Manager & Grid Control: Added 11g screen shots, Grid Control, and some Exadata

·        Chapter 6   Explain Plan, SQL Plan Management, DBMS_MONITOR, and TRCSESS

·        Chapter 7   Using Hints for Tuning: Added new hints and updated others—the best resource for hints!

·        Chapter 8   Basic Query Tuning: Updated for 11gR2; added Result Cache and SQL Performance Analyzer

·        Chapter 9   Table Joins & Advanced Tuning: Updated for 11gR2; updated block tuning and added DB Replay

·        Chapter 10   PL/SQL Tuning: Expanded again as PL/SQL tuning expands; added 11gR2 changes

·        Chapter 11   Exadata, RAC, & Parallel Features: Added Exadata, improved RAC, & updated Parallel Query

·        Chapter 12   The V$ Views: Expanded again to show more V$ view queries, especially those new in 11gR2

·        Chapter 13   The X$ Tables: Expanded X$ queries, trace section, and X$ naming conventions

·        Chapter 14   AWR Report & Statspack: Updated AWR, Statspack for 11gR2; added mutexes & block tuning

·        Chapter 15   Quick System Review: Updated for 11gR2 and for much larger systems

·        Chapter 16   Monitoring the System Using Unix Utilities: Unix chapter updated to include more commands

·        Appendix A   Key Initialization Parameters: Updated queries for 11gR2 & new Top 25 initialization parameters

·        Appendix B   V$ Views: Updated for 11gR2 with updated V$ view queries

·        Appendix C   X$ Tables: Updated for 11gR2 with updated X$ queries

沪ICP备14014813号-2

沪公网安备 31010802001379号