需要建立一张表来记录
成都创新互联是一家专注于网站建设、网站设计与策划设计,水富网站建设哪家好?成都创新互联做网站,专注于网站建设10余年,网设计领域的专业建站公司;建站业务涵盖:水富等地区。水富做网站价格咨询:13518219792
explain plan SET statement_id='name' FOR (这里是你要调试的语句 )
SELECT
A.OPERATION,
OPTIONS,
OBJECT_NAME,
OBJECT_TYPE,
ID,
PARENT_ID
FROM
PLAN_TABLE A
WHERE
STATEMENT_ID='name'
ORDER BY
Id;
ID 'name'是一个标识,你可以自己取,字段有很多个,以下是各个字段的解释(可能格式不对,你可以复制后看):
字段名 字段类型 含义
STATEMENT_ID VARCHAR2(30) explain PLAN 语句中所指定的最优STATEMENT_ID 参数值, 如果在EXPLAN PLAN语句中没有使用SET STATEMENT_ID,那么此值会被设为NULL。
REMARKS VARCHAR2(80) 与被解释规划的各步骤相关联的注释最长可达80 字节
OPERATION VARCHAR2(30) 各步骤所执行内部操作的名称在某条语句所产生的第一行中该列的可能取值如下DELETE STATEMENT INSERT STATEMENT SELECT STATEMENT UPDATE STATEMENT
OPTIONS VARCHAR2(30) 对OPERATION 列中所描述操作的变种
OBJECT_NODE VARCHAR2(128) 用于访问对象的数据库链接database link 的名称对于使用并行执行的本地查询该列能够描述操作中输出的次序
OBJECT_OWNER VARCHAR2(30) 对于包含有表或索引的架构schema 给出其所有者的名称
OBJECT_NAME VARCHAR2(30) 表或索引的名称
OBJECT_INSTANCE INTEGER 根据对象出现在原始original 语句中的次序所给出的相应次序编号就原始的语句文本而论其处理顺序为自左至右自外向内景象扩张view
OBJECT_TYPE VARCHAR2(30) 用于提供对象描述性信息的修饰符例如索引的NON-UNIQUE
OPTIMIZER VARCHAR2(255) 当前优化程序的模式
ID INTEGER 分配给执行规划各步骤的编号
PARENT_ID INTEGER 对ID 步骤的输出进行操作的下一个执行步骤的ID
POSITION INTEGER 对于具有相同PARENT_ID 的步骤其相应的处理次序
COST INTEGER 根据优化程序的基于开销的方法所估计出的操作开销值对于使用基于规则方法的语句该列为空该列值没有特定的测量单位它只是一个用于比较执行规划开销大小的权重值
CARDINALITY INTEGER 根据基于开销的方法对操作所访问行数的估计值
BYTES INTEGER 根据基于开销的方法对操作所访问字节的估计
=============================================
你按照我说的做,后面用
SELECT
*
FROM
PLAN_TABLE A
WHERE
STATEMENT_ID='name'
结果已经很清楚了,全部满足你的要求。
各列的具体含义上面已经给出。
基于以前开发的一个用于监控线程的CPU使用状况的小工具 TopShow 我开发了一个用于追踪Oracle内部函数调用的追踪器——OraTracer 你可以用该工具追踪监控Oracle多个内部函数的调用情况 还可以尝试探测函数的输入参数的值 也可以打印追踪点被触发时的调用堆栈 追踪可以设置在整个Oracle进程的级别 也可以设置在某个线程以追踪特定的会话
例子
捕获oracle整个实例中被执行的SQL语句
首先 在与可执行文件相同的目录下设置追踪点文件 TracePoints txt 内容如下
_opiprs *
_rpisplu *
_kprbprs
与函数名用空格相隔的数值为探测的参数数量 如果再加上 *N 则表示尝试将双字节数字作为指针对待 递归获取其执行的值 后面的数字为递归深度 例如 对于第一个追踪点 函数名为 _opiprs 探测 个参数 递归探测指针数据的深度为
注意 # 为注释符
然后从进程列表中选择 ORACLE EXE 不要选择任何线程
最后 点击 Trace 按钮 一旦有语句被上述函数调用 你就可以从监控窗口看到这些语句
SQL代码
…
[ : : ]User call: _rpisplu (TID: )
[Args( )]:
select privilege# level from sysauth$ connect by grantee#=prior privilege# and privilege# start with grantee#=: and privilege#
× (=NULL)
[ : : ]User call: _rpisplu (TID: )
[Args( )]:
alter session set NLS_LANGUAGE= AMERICAN NLS_TERRITORY= AMERICA NLS_CURRENCY= $ NLS_ISO_CURRENCY= AMERICA NLS_NUMERIC_CHARACTERS= NLS_DATE_FORMAT= DD MON RR NLS_DATE_LANGUAGE= AMERICAN NLS_SORT= BINARY
xd (=NULL)
[ : : ]User call: _opiprs (TID: )
[Args( )]:
× cce (= × )
alter session set NLS_LANGUAGE= AMERICAN NLS_TERRITORY= AMERICA NLS_CURRENCY= $ NLS_ISO_CURRENCY= AMERICA NLS_NUMERIC_CHARACTERS= NLS_DATE_FORMAT= DD MON RR NLS_DATE_LANGUAGE= AMERICAN NLS_SORT= BINARY
xd (=NULL)
× bfe (= × )
[ : : ]User call: _rpisplu (TID: )
[Args( )]:
× (=NULL)
× (=NULL)
select sysdate + / ( * ) from dual
× (=NULL)
[ : : ]User call: _rpisplu (TID: )
[Args( )]:
× (=NULL)
× (=NULL)
DECLARE job BINARY_INTEGER := :job; next_date DATE := :mydate; broken BOOLEAN := FALSE; BEGIN EMD_MAINTENANCE EXECUTE_EM_DBMS_JOB_PROCS(); :mydate := next_date; IF broken THEN :b := ; ELSE :b := ; END IF; END;
xd (=NULL)
…
点击 Stop 按钮 停止追踪
例子 :
理解SQL是如何被执行计划驱动执行的
我们知道 查询计划实际上就是驱动Oracle通过特定函数及顺序来获取数据 我们可以通过追踪这些函数来理解执行计划
首先下载以下文件 解压 重命名为 TracePoints txt 放到OraTracer exe所在目录
然后获取到你需要追踪的会话的SPID
SQL代码
HELLODBA select distinct spid from v$mystat m v$session s v$process p where s sid=m sid and s paddr=p addr;
SPID
————
从进程列表中选择ORACLE EXE = 从线程列表中选择TID为 的线程 = 点击 Trace 按钮
在被追踪的会话中执行一条语句
SQL代码
HELLODBA select * from demo t_test where owner= DEMO and object_name like T_TEST% ;
OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED
LAST_DDL_TIME TIMESTAMP STATUS T G S
—————————— —————————— —————————— ——— ————– —————— ———–
——– —————— —————— ——
DEMO T_TEST AAA TABLE
: : : : : : : VALID N N N
注意 为了避免回滚调用也被追踪 你最好在追踪之前先运行一次该语句
我们可以从追踪窗口看到数据fetch调用情况
SQL代码
[ : : ]User call: _qertbFetchByRowID (TID: )
[ : : ]User call: _qerixtFetch (TID: )
[ : : ]User call: _qertbFetchByRowID (TID: )
[ : : ]User call: _qerixtFetch (TID: )
有了这样的追踪记录 你可以尝试将他们与执行计划中节点映射
SQL代码
HELLODBA select * from demo t_test where owner= DEMO and object_name like T_TEST% ;
Execution Plan
———————————————————
Plan hash value:
——————————————————————————————
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
——————————————————————————————
| | SELECT STATEMENT | | | | ( )| : : |
| | TABLE ACCESS BY INDEX ROWID| T_TEST | | | ( )| : : | == _qertbFetchByRowID
|* | INDEX RANGE SCAN | T_TEST_IDX | | | ( )| : : | == _qerixtFetch
例子 :
打印某个特定函数被调用时的线程调用堆栈
我们这里追踪 _kkeAdjSingTabCard 设置追踪点
SQL代码
_kkeAdjSingTabCard*
函数名后的 *N 指定输出的调用个数 为无限制
然后获取到你需要追踪的会话的SPID
SQL代码
HELLODBA select distinct spid from v$mystat m v$session s v$process p where s sid=m sid and s paddr=p addr;
SPID
————
从进程列表中选择ORACLE EXE = 从线程列表中选择TID为 的线程 = 点击 Trace 按钮
在被追踪的会话中解释一条语句
SQL代码
HELLODBA explain plan for select /*+full(t)*/ count(*) from demo t_test t;
Explained
我们就可以从监控窗口获取到该函数被调用时的整个调用堆栈的情况
SQL代码
[ : : ]User call: _kkeAdjSingTabCard (TID: )
Call Stacks( ):
× (ORACLE EXE!_kkoitbp+ )
× c d (ORACLE EXE!_kkoijbad+ )
× d b (ORACLE EXE!_kkoCopyPreds+ )
× ee a (ORACLE EXE!_kkosta+ )
× d f c (ORACLE EXE!__PGOSF __apaRequestBindCapture+ )
× d (ORACLE EXE!_apagcp+ )
× d c (ORACLE EXE!_apafbr+ )
xea (ORACLE EXE!_opitcaNcp+ )
× b eb (ORACLE EXE!_kksMinimalTypeCheck+ )
× d (ORACLE EXE!_rpidrus+ )
× b ce (ORACLE EXE!_kksSetNLSHandle+ )
× e (ORACLE EXE!_kxsReleaseRuntimeLock+ )
× (ORACLE EXE!_kkscbt+ )
× e cf (ORACLE EXE!_kksParseCursor+ )
× f b (ORACLE EXE!_kksxscpat+ )
× e (ORACLE EXE!_opibrp+ )
× cd ed (ORACLE EXE!_kpodrd+ )
× cba c (ORACLE EXE!_kpocrs+ )
× e (ORACLE EXE!_opirip+ )
× feff (oramon dll!_ttcpro+ )
× a (ORACLE EXE!_opiodr+ )
× (ORACLE EXE!_opiino + )
× e (ORACLE EXE!_opirip+ )
× e (ORACLE EXE!_opidcl+ )
× a (ORACLE EXE!_ksdwri+ )
× (ORACLE EXE!_ssthrnfy+ )
× (ORACLE EXE!_opimai_init+ )
× (ORACLE EXE!_osnsoiint+ )
× c b (KERNEL dll!GetModuleFileNameA+ )
[Args( )]:
× e d
× e da
× a
×
lishixinzhi/Article/program/Oracle/201311/18739
用toad 的工具可以进行跟踪。查找toad的路径 右键属性 查找相应文件夹 然后 找寻同级目录下的 sql_monitor 这个工具就可以对 Oracle运行数据进行跟踪。