如何干预执行计划

使用hints提示:
基于代价的优化器在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。此时就需要DBA进行人为的干预,告诉优化器使用我们指定的存取路径或连接类型生成执行计划,从而使语句高效的运行。例如: 对于一个特定的语句,执行全表扫描要比执行索引扫描更有效,则我们可以指示优化器使用全表扫描。在ORACLE中,是通过为语句添加hints(提示)来实现干预优化器优化的目的。
hints是oracle提供的一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划。可以用hints来实现:
1) 使用的优化器的类型
2) 基于代价优化器的优化目标,是all_rows还是first_rows。
3) 表的访问路径,是全表扫描、索引扫描,还是直接利用rowid。
4) 表之间的连接类型
5) 表之间的连接顺序

6) 语句的并行程度


如何使用hints:
Hints只应用在它们所在sql语句块(statement block,由select、update、delete关键字标识)上,对其它SQL语句或语句的其它部分没有影响。如:对于使用union操作的2个sql语句,如果只在一个sql语句上有hints,则该hints不会影响另一个sql语句。
可以使用注释(comment)来为一个语句添加hints,一个语句块只能有一个注释,而且注释只能放在SELECT, UPDATE, or DELETE关键字的后面。
使用hints的语法:
{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */
or
{DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...
注解:
1) DELETE、INSERT、SELECT和UPDATE是标识一个语句块开始的关键字,包含提示的注释只能出现在这些关键字的后面,否则提示无效。
2) “+”号表示注释是一个hints,加号必须立即跟在”/*”后面,中间不能有空格。
3) hint是下面介绍的具体提示之一,如果包含多个提示,则每个提示之间需要用一个或多个空格隔开。
4) text 是其它说明hint的注释性文本
如果你没有正确的指定hints,Oracle将忽略该hints,并且不会给出任何错误。 

使用全套的hints:
当使用hints时,在某些情况下,为了确保让优化器产生最优的执行计划,我们可能指定全套的hints。例如,如果有一个复杂的查询,包含多个表连接,如果你只为某个表指定了INDEX提示(指示存取路径在该表上使用索引),优化器需要来决定其它应该使用的访问路径和相应的连接方法。因此,即使你给出了一个INDEX提示,优化器可能觉得没有必要使用该提示。这是由于我们让优化器选择了其它连接方法和存取路径,而基于这些连接方法和存取路径,优化器认为用户给出的INDEX提示无用。为了防止这种情况,我们要使用全套的hints,如:不但指定要使用的索引,而且也指定连接的方法与连接的顺序等。
下面是一个使用全套hints的例子,ORDERED提示指出了连接的顺序,而且为不同的表指定了连接方法:
SELECT /*+ ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b)
USE_NL (glcc glf) USE_MERGE (gp gsb) */
b.application_id, b.set_of_books_id ,
b.personnel_id, p.vendor_id Personnel,
p.segment1 PersonnelNumber, p.vendor_name Name
FROM jl_br_journals j, jl_br_balances b,
gl_code_combinations glcc, fnd_flex_values_vl glf,
gl_periods gp, gl_sets_of_books gsb, po_vendors p
WHERE ...

指示优化器的方法与目标的hints:
ALL_ROWS -- 基于代价的优化器,以吞吐量为目标
FIRST_ROWS(n) -- 基于代价的优化器,以响应时间为目标
CHOOSE -- 根据是否有统计信息,选择不同的优化器
RULE -- 使用基于规则的优化器
例子:
SELECT /*+ FIRST_ROWS(10) */ employee_id, last_name, salary, job_id
FROM employees
WHERE department_id = 20;
SELECT /*+ CHOOSE */ employee_id, last_name, salary, job_id
FROM employees
WHERE employee_id = 7566;

SELECT /*+ RULE */ employee_id, last_name, salary, job_id
FROM employees
WHERE employee_id = 7566;

指示存储路径的hints:
FULL /*+ FULL ( table ) */
指定该表使用全表扫描
ROWID /*+ ROWID ( table ) */
指定对该表使用rowid存取方法,该提示用的较少
INDEX /*+ INDEX ( table [index]) */
使用该表上指定的索引对表进行索引扫描
INDEX_FFS /*+ INDEX_FFS ( table [index]) */
使用快速全表扫描
NO_INDEX /*+ NO_INDEX ( table [index]) */
不使用该表上指定的索引进行存取,仍然可以使用其它的索引进行索引扫描
SELECT /*+ FULL(e) */ employee_id, last_name FROM employees e
WHERE last_name LIKE :b1;
SELECT /*+ROWID(employees)*/ * FROM employees
WHERE rowid > 'AAAAtkAABAAAFNTAAA' AND employee_id = 155;
SELECT /*+ INDEX(A sex_index) use sex_index because there are few
male patients */ A.name, A.height, A.weight
FROM patients A WHERE A.sex = ’m’;
SELECT /*+NO_INDEX(employees emp_empid)*/ employee_id FROM employees
WHERE employee_id > 200;

指示连接顺序的hints:
ORDERED /*+ ORDERED */
按from 字句中表的顺序从左到右的连接
STAR /*+ STAR */
指示优化器使用星型查询

SELECT /*+ORDERED */ o.order_id, c.customer_id, l.unit_price * l.quantity
FROM customers c, order_items l, orders o
WHERE c.cust_last_name = :b1
AND o.customer_id = c.customer_id
AND o.order_id = l.order_id;
/*+ ORDERED USE_NL(FACTS) INDEX(facts fact_concat) */ 

指示连接类型的hints:

USE_NL /*+ USE_NL ( table [,table, ...] ) */
使用嵌套连接
USE_MERGE /*+ USE_MERGE ( table [,table, ...]) */
使用排序- -合并连接
USE_HASH /*+ USE_HASH ( table [,table, ...]) */
使用HASH连接

以上示例得出:
通过给语句添加HINTS,让其按照我们的意愿执行,有时是一件很困难的事情,需要不断的尝试各种不同的hints。对于USE_NL与USE_HASH提示,建议同ORDERED提示一起使用,否则不容易指定那个表为驱动表。

总 结
两个以上的查询都是采用nested loop循环,这时采用哪个表作为driving table就很重要。在第一个sql中,小表(SUPER_USER)作为driving table,符合oracle优化的建议,但是由于SWD_BILLDETAIL表中cn列的值有很多重复的,这样对于SUPER_USER中的每一行,都会在SWD_BILLDETAIL中有很多行,利用索引查询出这些行的rowid很快,但是再利用这些rowid去查询SWD_BILLDETAIL表中的user_class列的值,就比较慢。原因是这些rowid是随机的,而且该表比较大,不可能缓存到内存,所以几乎每次按照rowid查询都需要读物理磁盘,这就是该执行计划比较慢的真正原因。从结果可以得到验证:查询 出1186387行,需要利用rowid从SWD_BILLDETAIL表中读取1186387次,而且大部分为从硬盘上读取。 
如果利用大表(SWD_BILLDETAIL)作为driving表,这样大表只需要做一次全表扫描(而且会使用多块读功能,每次物理I/O都会读取几个oracle数据块,从而一次读取很多行,加快了执行效率),对于读出的每一行,都与SUPER_USER中的行进行匹配,因为SUPER_USER表很小,所以可以全部放到内存中,这样匹配操作就极快,所以该sql执行的时间与SWD_BILLDETAIL表全表扫描的时间差不多(SWD_BILLDETAIL全表用11分钟,而此查询用20分钟)。
另外:如果SWD_BILLDETAIL表中cn列的值唯一,则第一个sql执行计划执行的结果或许也会不错。如果SUPER_USER表也很大,如500万行,则第2个sql执行计划执行的结果反而又可能会差。其实,如果SUPER_USER表很小,则第2个sql语句的执行计划如果不利用SUPER_USER表的索引,查询或许会更快一些,我没有对此进行测试。
总之:在进行性能调整时,具体问题要具体分析,没有一个统一的标准。

注意事项
一个语句在运行时到底使用何种优化器可以从下面的表格中识别出来,从上到下看你的语句到底是否满足description列中描述的条件:
Description 对象是否被分析 优化器的类型
~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~
Non-RBO Object (Eg:IOT) n/a #1
Parallelism > 1 n/a #1
RULE hint n/a RULE
ALL_ROWS hint n/a ALL_ROWS
FIRST_ROWS hint n/a FIRST_ROWS
*Other Hint n/a #1
OPTIMIZER_GOAL=RULE n/a RULE
OPTIMIZER_GOAL=ALL_ROWS n/a ALL_ROWS
OPTIMIZER_GOAL=FIRST_ROWS n/a FIRST_ROWS
OPTIMIZER_GOAL=CHOOSE NO RULE
OPTIMIZER_GOAL=CHOOSE YES ALL_ROWS

#1 表示除非OPTIMIZER_GOAL 被设置为FIRST_ROWS ,否则将使用ALL_ROWS。在PL/SQL中,则一直是使用ALL_ROWS 。*Other Hint 表示是指除RULE、ALL_ROWS 和FIRST_ROWS以外的其它提示 。

当CBO选择了一个次优化的执行计划时, 不要同CBO过意不去, 先采取如下措施:
1) 检查是否在表与索引上有最新的统计数据
2) 对所有的数据进行分析,而不是只分析一部分数据
3) 检查是否引用的数据字典表,在oracle 10G之前,缺省情况下是不对数据字典表进行分析的。
4) 试试RBO优化器,看语句执行的效率如何,有时RBO能比CBO产生的更好的执行计划
5) 如果还不行,跟踪该语句的执行,生成trace信息,然后用tkprof格式化trace信息,可以得到全面的供优化的信息。


假如利用附录的方法对另一个会话进行trace,则该会话 应该为专用连接 。
不要认为绑定变量(bind variables)的缺点只有书写麻烦,而优点多多,实际上使用绑定变量虽然避免了重复parse,但是它导致优化器不能使用数据库中的列统计,从而选择了较差的执行计划。而使用硬编码的SQL则可以使用列统计。当然随着CBO功能的越来越强,这种情况会得到改善。目前就已经实现了在第一次运行绑定变量的sql语句时,考虑列统计。
如果一个row source 超过10000行数据,则可以被认为大row source 。
有(+)的表不是driving table,注意:如果有外联接,而且order hint指定的顺序与外联结决定的顺序冲突,则忽略order hint。
影响CBO选择execution plan的初始化参数:
这些参数会影响cost值
ALWAYS_ANTI_JOIN
B_TREE_BITMAP_PLANS
COMPLEX_VIEW_MERGING
DB_FILE_MULTIBLOCK_READ_COUNT
FAST_FULL_SCAN_ENABLED
HASH_AREA_SIZE
HASH_JOIN_ENABLED
HASH_MULTIBLOCK_IO_COUNT
OPTIMIZER_FEATURES_ENABLE
OPTIMIZER_INDEX_CACHING
OPTIMIZER_INDEX_COST_ADJ
OPTIMIZER_MODE> / GOAL
OPTIMIZER_PERCENT_PARALLEL
OPTIMIZER_SEARCH_LIMIT
PARTITION_VIEW_ENABLED
PUSH_JOIN_PREDICATE
SORT_AREA_SIZE
SORT_DIRECT_WRITES
SORT_WRITE_BUFFER_SIZE
STAR_TRANSFORMATION_ENABLED
V733_PLANS_ENABLED
CURSOR_SHARING

概括介绍,跟踪一个客户程序发出的SQL主要分成下面几步:
识别要跟踪的客户端程序到数据库的连接(后面都用session代替),主要找出能唯一识别一个session的sid与serial#。
设定相应的参数,如打开时间开关(可以知道一个sql执行了多长时间),存放跟踪数据的文件的位置、最大值。
启动跟踪功能。
让系统运行一段时间,以便可以收集到跟踪数据。
关闭跟踪功能。
格式化跟踪数据,得到我们易于理解的跟踪结果。

1) 识别要跟踪的客户端程序到数据库的数据库连接
查询session信息(在sql*plus中运行):
set linesize 190
col machine format a30 wrap
col program for a40
col username format a15 wrap
set pagesize 500
select s.sid sid, s.SERIAL# "serial#", s.username, s.machine, s.program,
p.spid ServPID, s.server
from v$session s, v$process p
where p.addr = s.paddr ;

如得到的一个查询结果如下:

SID serial# USERNAME MACHINE PROGRAM SERVPID SERVER
---- ------- -------- ------------------ ------------- --------- ---------
8 3 SCOTT WORKGROUP\SUNNYXU SQLPLUS.EXE 388 DEDICATED
LOGON_TIME
------------------
2005.06.28 18:50:11
上面的结果中比较有用的列为:
sid, serial# : 这两个值联合起来唯一标识一个session
username : 程序连接数据库的用户名
machine : 连接数据库的程序所在的机器的机器名,可以hostname得到
program : 连接数据库的程序名,所有用java jdbc thin的程序的名字都一样,
servpid : 与程序对应的服务器端的服务器进程的进程号,在unix下比较有用
server : 程序连接数据库的模式:专用模式(dedicaed)、共享模式(shared)。
只有在专用模式下的数据库连接,对其进程跟踪才有效
logon_time : 程序连接数据库的登陆时间
根据machine, logon_time 可以方便的识别出一个数据库连接对应的session,从而得到该sesion的唯一标识sid, serial#, 为对该session进行跟踪做好准备
2) 设定相应的参数
参数说明:
timed_statistics : 收集跟踪信息时,是否将收集时间信息,如果收集,
则可以知道一个sql的各个执行阶段耗费的时间情况
user_dump_dest : 存放跟踪数据的文件的位置
max_dump_file_size : 放跟踪数据的文件的最大值,防止由于无意的疏忽,
使跟踪数据的文件占用整个硬盘,影响系统的正常运行
设置的方法:
SQL> exec sys.dbms_system.set_bool_param_in_session( -
sid => 8, -
serial# => 3, -
parnam => 'timed_statistics', -
bval => true);
SQL> alter system set user_dump_dest='c:\temp';
-- 注意这个语句会改变整个系统的跟踪文件存放的位置,所以我一般不改这个参数,而用系统的缺省值,要查看当前系统的该参数的值,可以用system用户登陆后:
SQL> show parameter user_dump_dest
SQL> exec sys.dbms_system.set_int_param_in_session( -
sid => 8, -
serial# => 3, -
parnam => 'max_dump_file_size', -
intval => 2147483647)
3) 启动跟踪功能
SQL> exec sys.dbms_system.set_sql_trace_in_session(8, 3, true);
注意,只有跟踪的session再次发出sql语句后,才会产生trc文件
4) 让系统运行一段时间,以便可以收集到跟踪数据
5) 关闭跟踪功能
SQL> exec sys.dbms_system.set_sql_trace_in_session(8,3,false);
6) 格式化跟踪数据,得到我们易于理解的跟踪结果。

对产生的trace文件进行格式化:

在命令提示符下,运行下面的命令
tkprof dsdb2_ora_18468.trc dsdb2_trace.out SYS=NO EXPLAIN=SCOTT/TIGER

其它使用tkprof的例子:
(a) tkprof tracefile.trc sort_1.prf explain=apps/your_apps_password print=10 sort='(prsqry,exeqry,fchqry,prscu,execu,fchcu)' (b) tkprof tracefile.trc sort_2.prf explain=apps/your_apps_password print=10 sort='(prsela,exeela,fchela)' (c) tkprof tracefile.trc sort_3.prf explain=apps/your_apps_password print=10 sort='(prscnt,execnt,fchcnt)' (d) tkprof tracefile.trc normal.prf explain=apps/your_apps_password
现对tkprof程序做进一步的说明:
在打开跟踪功能后,oracle将被跟踪session中正在执行的SQL的性能状态数据都收集到一个跟踪文件中。这个跟踪文件提供了许多有用的信息,例如一个sql的解析次数、执行次数、fetch次数、物理读次数、逻辑读次数、CPU使用时间等,利用这些信息可以诊断你的sql的问题,从而用来优化你的系统。不幸的是,生成的跟踪文件中的数据是我们难以理解的,所以要用TKPROF工具对其进行转换,转换成我们易于理解格式。tkprof是oracle提供的实用工具,类似于sql*plus,在安装完oracle客户端后就自动安装到系统中,直接在命令符下用就可以了。
当在打开跟踪功能时发生了recursive calls,则tkprof也会产生这些recursive calls的统计信息,并清楚的在格式化输出文件中标名它们为recursive calls。
注意:recursive calls的统计数据是包含在recursive calls上的,并不包含在引起该recursive calls语句的sql语句上面。所以计算一个sql语句耗费的资源时,也要考虑该sql语句引起recursive calls语句花费的资源。通过将sys参数设为no时,我们变可以在格式化的输出文件中屏蔽掉这些recursive calls信息。
如何得到tkprof的帮助信息:
运行tkprof时,不带任何参数,就可以得到该工具的帮助信息。

执行计划:
---------------
一个语句的执行计划是oracle执行这个sql语句的一系列指令。通过检验执行计划,你可以更好的知道oracle如何执行你的sql语句,这个信息可以帮助你决定是否你写的sql语句已经使用了索引。
如果在tkprof中指定了EXPLAIN参数,tkprof使用EXPLAIN PLAN命令来为每个被跟踪的sql语句产生执行计划。
使用说明:
TKPROF工具接受一个trace文件作为输入文件,利用提供给命令的多个参数对trace文件进行分析,然后将格式化好的结果放到一个输出文件中。
TKPROF的使用语法:
----------------
TKPROF command ::=
>>-- TKPROF traced_file formatted_file ---------------------------------------------->
| |
+- SORT = ---------------------------------+
| |
+-- OPTION --+
| |
| +---- , ----+ |
| V | |
|__( OPTION )__|
>----------------------------------------------------------------------------->
| | | | | |
+-- PRINT = integer --+ +-- INSERT = filname3 --+ +-- SYS = ---------+
| |
+- YES -+
| |
+- NO --+
>----------------------------------------------------------------------------->
| |
+---------------------------------------- EXPLAIN = user/password ------+
| |
+---- TABLE = schema.table ----+
>----------------------------------------------------------------------------><
| |
+---- RECORD = filname ----+
各个参数的含义:
' traced_file '
指定输入文件,即oracle产生的trace文件,该文件中可以只包含一个
session的跟踪信息,也可以包含系统中所有session的信息(此时需要在
系统级进行跟踪)
'formatted_file'
指定输出文件,即我们想得到的易于理解的格式化文件,我们利用该文件
对会话运行的sql进行分析。
'EXPLAIN'
利用哪个用户对trace文件中的sql进行分析,从而得到该sql语句的
执行计划,这也说明在trace file中并没有各个sql语句的执行计划,只是在运
行tkprof程序时才将trace file文件中的sql语句用explian参数指定的
用户连接到数据库,然后运用EXPLAIN PLAN命令生成sql的执行计划。

这个用户一般是你的程序中连接数据库的用户
'TABLE'
在对sql语句进行分析时,将产生的执行计划暂时存放到该表中。
一般不需要该参数,这样当表不存在时,tkprof会自动创建相应的表,
并在分析完之后,将创建的表自动删除。如果要指定自定义的表,该表的结构
必须与utlxplan.sql文件中指定的表的结构一样。
我一般不设置这个参数,让其采用默认的表名,并自动创建、删除
'SYS'
是否对sys用户运行的sql语句或被跟踪session产生的recursive SQL
也进行分析,并将分析结果放到输出文件中。缺省值为YES。
我一般设为NO,这样输出文件中只包含我发出的sql语句,
而不包含系统产生的sql。
SORT
按照指定的排序选项(条件)对格式化好的sql语句进行降序排列,然后存放
到输出文件中。可以将多个排序选项组合起来,如果没有指定排序选项,
则按照使用sql的先后顺序。
排序选项有:
prscnt number of times parse was called
prscpu cpu time parsing
prsela elapsed time parsing
prsdsk number of disk reads during parse
prsqry number of buffers for consistent read during parse
prscu number of buffers for current read during parse
prsmis number of misses in library cache during parse
execnt number of execute was called
execpu cpu time spent executing
exeela elapsed time executing
exedsk number of disk reads during execute
exeqry number of buffers for consistent read during execute
execu number of buffers for current read during execute
exerow number of rows processed during execute
exemis number of library cache misses during execute
fchcnt number of times fetch was called
fchcpu cpu time spent fetching
fchela elapsed time fetching
fchdsk number of disk reads during fetch
fchqry number of buffers for consistent read during fetch
fchcu number of buffers for current read during fetch
fchrow number of rows fetched
userid userid of user that parsed the cursor
PRINT
只列出指定数量的已排序的sql语句,排序的条件参见SORT参数。
如果忽略此参数,tkprof将跟踪文件中的所有的sql语句及其相关的

分析数据存放到输出文件中。
Print与sort参数组合在一起,可以实现:
找出某一阶段耗费cpu最多的前n个sql
找出某一阶段读硬盘最多的前n个sql等等。
INSERT
创建一个sql脚本文件,里面包含create table 与insert语句。
利用这个脚本文件创建一个表及插入数据后,可以得到跟踪文件中
所有sql语句(包含recursive SQL)的统计信息。如
,depth,user_id,
parse_cnt,parse_cpu,parse_elap,parse_disk,
parse_query,parse_current,parse_miss
,exe_count,exe_cpu,exe_elap,exe_disk,exe_query,
exe_current,exe_miss,exe_rows
,fetch_count,fetch_cpu,fetch_elap,fetch_disk,
fetch_query,fetch_current,fetch_rows,ticks
,sql_statement。
利用这些信息,也可以发现有问题的sql。即是格式化好的输出文件中
有关sql性能信息数据的数据库表的形式。
我一般不用该参数
RECORD
创建一个包含客户端程序发出的所有的sql语句的脚本文件。
注意,并不包含recursive SQL 。想知道它的用处吗?
对了可以窥探别人程序是如何访问数据库的,从而对了解程序的访问流程。
此时,最好不用sort参数,这样就可以按先后发出的顺序的到sql.
例子1:
将跟踪文件"dsdb2_ora_18468.trc"进行分析,并将其格式的结果放到"dsdb2_trace.out"文件中:
TKPROF dsdb2_ora_18468.trc dsdb2_trace.out SYS=NO EXPLAIN=SCOTT/TIGER
上面的例子中:
EXPLAIN参数让TKPROF程序连接到SCOTT用户,然后用EXPLAIN PLAN命令给跟踪文件中的sql语句产生执行计划。SYS参数的值为NO,这样TKPROF就会忽略该跟踪文件中的recursive SQL。
例子2:
TKPROF DLSUN12_JANE_FG_SVRMGR_007.TRC OUTPUTA.PRF
EXPLAIN=SCOTT/TIGER TABLE=SCOTT.TEMP_PLAN_TABLE_A
INSERT=STOREA.SQL SYS=NO SORT=(EXECPU,FCHCPU)
注意上面的所有命名应该都在一行中,否则需要有换行符。
上面的例子中:
TABLE参数使TKPROF使用scott用户下的TEMP_PLAN_TABLE_A表作为临时存放sql执行计划的表。
INSERT参数使TKPROF产生一个名为STOREA.SQL的脚本文件,存放所有被跟踪的sql语句的统计数据。
SORT参数使TKPROF先按照sql语句使用的cpu执行时间与该语句fetch操作使用的cpu时间进行排序,然后将其写到输出文件中。
解释tkprof程序产生的格式化文件:
tkprof的格式化输出文件主要包含两大部分:
header
body
summary
header:
主要包括一些描述信息,如TKPROF的版本、运行时间,各个统计项的描述。如:
TKPROF: Release 8.1.7.0.0 - Production on 星期四 6月 30 13:10:59 2005
(c) Copyright 2000 Oracle Corporation. All rights reserved.
Trace file: D:\oracle\admin\xyj\udump\ORA01720.TRC
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
body:
是我们主要关心的地方,有我们感兴趣的信息。如sql语句、sql语句的统计信息、sql语句的执行计划等。如
select *
from
emp
call count cpu elapsed disk query current rows
------- ----- ----- ------- ----- ------ -------- -----
Parse 3 0.00 0.00 1 0 1 0
Execute 3 0.00 0.00 0 0 0 0
Fetch 6 0.00 0.00 1 6 12 36
------- ----- ----- ------- ----- ------ -------- -----
total 12 0.00 0.00 2 6 13 36
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 19 (SCOTT)
Rows Row Source Operation
------- ---------------------------------------------------
12 TABLE ACCESS FULL EMP
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT GOAL: CHOOSE
12 TABLE ACCESS (FULL) OF 'EMP'
DELETE FROM RM$HASH_ELMS
call count cpu elapsed disk query current rows
------- ------ ------ -------- ----- ------ -------- ----
Parse 2 0.00 0.00 0 0 0 0
Execute 29 12.04 12.61 6786 6853 108 19
Fetch 0 0.00 0.00 0 0 0 0
------- ------ ------ -------- ----- ------ -------- ----
total 31 12.04 12.61 6786 6853 108 19
Misses in library cache during parse: 0
Optimizer hint: CHOOSE
Parsing user id: 9 (DES12A) (recursive depth: 3)
Rows Execution Plan
------- ---------------------------------------------------
0 DELETE STATEMENT HINT: CHOOSE
16 TABLE ACCESS (FULL) OF 'RM$HASH_ELMS'
summary:
对所有的sql语句各个执行阶段的统计数据的汇总:
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS - - 标明是用户发出的sql语句的统计数据的汇总
call count cpu elapsed disk query current rows
------- ------ -------- -------- ----- ------ -------- -----
Parse 7 0.00 0.00 2 201 2 0
Execute 7 0.00 0.00 1 2 7 1
Fetch 10 0.00 0.00 2 67 16 52
------- ------ -------- -------- ----- ------ -------- -----
total 24 0.00 0.00 5 270 25 53
Misses in library cache during parse: 5
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS - - 标明是系统发出的sql语句的统计数据的汇总
call count cpu elapsed disk query current rows
------- ------ ------ -------- ----- ------ -------- ----
Parse 75 0.00 0.00 2 3 2 0
Execute 81 0.00 0.00 1 1 5 1
Fetch 153 0.00 0.00 21 355 0 110
------- ------ ------ -------- ----- ------ -------- ----
total 309 0.00 0.00 24 359 7 111
Misses in library cache during parse: 29
8 user SQL statements in session.
74 internal SQL statements in session.
82 SQL statements in session.
5 statements EXPLAINed in this session.
*********************************************************************
Trace file: D:\oracle\admin\xyj\udump\ORA01720.TRC
Trace file compatibility: 8.00.04
Sort options: default
1 session in tracefile.
8 user SQL statements in trace file.
74 internal SQL statements in trace file.
82 SQL statements in trace file.
34 unique SQL statements in trace file.
5 SQL statements EXPLAINed using schema:
SCOTT.prof$plan_table
Default table was used.
Table was created.
Table was dropped.
825 lines in trace file.
现只对body中的每部分作出详细说明:
1) sql语句的统计信息
我们把select语句的执行过程分成3个阶段(分析

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

mongodb replica sets复制集详解 - 2016-06-08 17:06:37

一.replica sets介绍 一个复制集是一组包含相同数据集的mongod实例.一个复制集只能有一个是primary节点,其它的节点为secondary节点. 和主从复制的原理一样,复制集也是通过读取oplog来进行数据传输.oplog是一个capped collection即固定表,创建表的时候可以指定其大小,当oplog满的时候会删除旧的数据. 所以设置oplog的大小非常重要,如果oplog在primary节点被覆盖而尚未被secondary节点读取的话就要重新resync. 一般的使用repl

MySql-主从复制 - 2016-06-08 14:06:52

一、概述 1、原理 复制(Replication)是从一台MySQL数据库服务器(主服务器master)复制数据到另一个服务器(从服务器slave)的一个进程。 主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。 当进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,你必须要小心

Mongo DB安装及配置 - 2016-06-08 14:06:26

一,安装 环境:Ubuntu14.04 安装mongoldb: sudo apt-key adv --keyserver  hkp://keyserver.ubuntu.com:80  --recv EA312927  echo "deb  http://repo.mongodb.com/apt/ubuntu  trusty/mongodb-enterprise/stable multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-enterprise

Redis内部数据结构的实现 - 2016-06-07 17:06:52

还有两个多月就找工作了,决定把之前看的一些东西整理一下,做个记录,也整理一下最近的思路。 Redis 作为一个基于key=value的内存数据库,使用ANSI C语言实现,以其高性能和支持丰富的数据结构闻名于世,而其数据结构也是其高性能的基础,今天分享一下我对此的理解,并以redis3.2的正式版源码分析。 在Redis内部,有非常多的数据结构:sds(简单动态字符串),list,intset(整数集合),hash(字典),zskiplist(跳跃表),ziplist(压缩表)等。 1. sds type
      信息函数       常用的信息函数有:       (1)查看数据库连接ID和当前数据库       SELECT CONNECTION_ID();       SELECT DATABASE();       (2)查看最后输入记录的ID号       ALTER TABLE test ADD id SMALLINT UNSIGNED KEYAUTO_INCREMENT  FIRST;       INSERT test(first_name,last_name) VALUES('11',
return service指在复制源和目标之间的同步模式,可以是no return(异步),return receipt(准同步)和return twosafe(全同步)。 本文的描述对于active standby和classic replication都适用。 脚本准备 $ cat insert1.sql INSERT INTO employees VALUES ( 202, ‘Pat’, ‘Fay’, ‘PFAY’, ‘603-123-7777’, TO_DATE(‘17-AUG-1997’, ‘

MySql-InnoDB-缓存管理 - 2016-06-07 14:06:27

MySql内存结构 InnoDB主索引是聚簇索引,索引与数据共用表空间,对于InnoDB而言,数据就是索引,索引就是数据。InnoDB缓存机制和MyISAM缓存机制的最大区别就是在于,InnoDB不仅仅是缓存索引,还会缓存数据。 InnoDB缓存池 InnoDB缓存池(InnoDB buffer pool)是InnoDB性能提升的核心,它既可以缓存数据还可以缓存索引,甚至其他管理数据(例如元数据信息,行级锁信息)。 使用MySQL命令”show variables like ‘innodb%pool%’;
三种方式简单实现数据持久化功能 文件存储 简介 将数据存储到文件中 从文件中读取数据 扩展StringStringBuilderStringBuffer SharePreferences存储 注意点 获取SharePreferences对象的三种方式 Context类中的 getSharedPreferences方法 Activity类中的 getPreferences方法 PreferenceManager类中的 getDefaultSharedPreferences方法 向SharedPreferen
        一自定义函数简介         (1)自定义函数定义         用户自定义函数(user-defined function,UDF)是一种对MySQL数据库扩展的途径,其用法与内置函数相同。         (2)自定义函数的两个必要条件         1)参数:可以有零个或多个。         2)返回值:只能有一个返回值。        使用自定义函数的注意事项        1)所有函数都有返回值,但不一定都有参数。        2)函数的参数与返回值之间没有必然的内在
在这个用数据说话的时代(靠脸吃饭的年代),没有一个好的展现形态(没有一张帅气清秀的脸蛋),对于整个产 品产生的影响,那简直... 在数据可视化竞争的战场,互联网的各家各户都很注重自家产品的前端展现。这也造成了目前前端各种火到爆,火的不要不要的原因之一。各类新型的框架也是接踵而至,如:emberjs、angluarjs、backbonejs、vuejs以及reactjs等等,这个对目前企业的发展也造成了一定的困扰。 追星派 : 此派弟子非常注重对新技能的渴求,看到新的技能书,不管前方道路如何坎坷,练了再说。