Know more about CBO Index Cost

近日偶读Joze Senegacnik(他是一名ACE)在OOW 2011上做的《Getting The Best From The Cost Based Optimizer》Presentation(这里可以下载),发现他总结的索引Unique Scan和Range Scan成本计算公式总结地很不错,贴出来共享:

 

Index Unique Scan Cost INDEX UNIQUE SCAN COST = (BLEVEL (1-(OIC/100)) + 1) * (OICA/100)

 

Index Range Scan Cost INDEX RANGE SCAN COST = (BLEVEL + FF*LFBL)*(1-(OIC/100))+ FF*CLUF)* (OICA/100)

 

 

formula does not include the CPU cost

BLEVEL = number . . . → Read More: Know more about CBO Index Cost

Script:SQL调优健康检查脚本

SQLHC1

以下脚本可以用于收集SQL调优的相关信息,包括统计信息、优化器参数等。

When executed for one SQL_ID, this script generates an HTML report with the results of a set of health-checks around the one SQL statement provided. Health-checks are performed over:

CBO Statistics for schema objects accessed by the one SQL statement being analyzed CBO Parameters CBO System Statistics CBO Data Dictionary Statistics CBO Fixed-objects Statistics . . . → Read More: Script:SQL调优健康检查脚本

Know more about AWR Parse Statistics

Parse CPU to Parse Elapsed%是一个我们在分析AWR报告时常会看到的解析性能指标,该指标反映了 快照内解析CPU时间和总的解析时间的比值(Parse CPU Time/ Parse Elapsed Time); 若该指标水平很低,那么说明在整个解析过程中 实际在CPU上运算的时间是很短的,而主要的解析时间都耗费在各种其他非空闲的等待事件上了(如latch:shared pool,row cache lock之类等), 通过该指标我们可以了解是否有必要来调优Oracle的优化器Optimizer的解析(parse)工作, 调优的对象包括软、硬解析(soft and hard parse),理论上我们的目标是有极少的硬解析,少量的软解析,以及Parse CPU to Parse Elapsed% 接近于100% 相当于解析时都是在CPU上运算 而不等待, 所以Parse CPU to Parse Elapsed%也同时给我们以调优方向的启示。

 

Soft Parse %是AWR中另一个重要的解析指标,该指标反应了快照时间内 软解析次数 和 总解析次数 (soft+hard 软解析次数+硬解析次数)的比值,若该指标很低,那么说明了可能存在剧烈的hard parse硬解析,大量的硬解析会消耗更多的CPU时间片并产生解析争用(此时可以考虑使用cursor_sharing=FORCE); 理论上我们总是希望 Soft Parse % 接近于100%, 但并不是说100%的软解析就是最理想的解析状态,通过设置 session_cached_cursors参数和反复重用游标我们可以让解析来的更轻量级,即通俗所说的利用会话缓存游标实现的软软解析(soft soft parse)。

 

其他一些对于tuning SQL . . . → Read More: Know more about AWR Parse Statistics

Oracle Enterprise Manager 12c 新特性:实时Real-Time Addm

在Oracle Enterprise Manager 12c中引入了Real-Time addm的新特性。 DBA可以直接从EM界面上启动实时ADDM(Automatic Database Diagnostic Monitor )信息收集, 也叫做Emergency ADDM。

 

“Emergency ADDM adds performance diagnostics for databases suffering from severe performance problems. Real-time ADDM. You can connect to the database and investigate what is going on when you cannot connect to the database because it is hanging on“

 

 

登录EM 12c后Target . . . → Read More: Oracle Enterprise Manager 12c 新特性:实时Real-Time Addm

CBO为什么不走索引?

histogram_script_view

原帖是Itpub上的网友提出一个CBO为什么不走索引的问题, 该问题的演示如下:

 

SQL> create table maclean1 as select * from dba_objects; Table created. SQL> update maclean1 set status=’INVALID’ where owner=’MACLEAN’; 2 rows updated. SQL> commit; Commit complete. SQL> create index ind_maclean1 on maclean1(status); Index created. SQL> exec dbms_stats.gather_table_stats(‘SYS’,'MACLEAN1′,cascade=>true); PL/SQL procedure successfully completed. SQL> explain plan for select * from maclean1 where status=’INVALID’; Explained. SQL> . . . → Read More: CBO为什么不走索引?

何时会发生db file sequential read等待事件?

很多网友对系统内频繁发生的db file sequential read等待事件存有疑问,那么到底在那些场景中会触发该单块读等待事件呢?

在我之前写的一篇博文<SQL调优:Clustering Factor影响数据删除速度一例>中总结了db file sequential read等待事件可能发生的场景,在这里再share以下:

”db file sequential read”单块读等待是一种最为常见的物理IO等待事件,这里的sequential指的是将数据块读入到相连的内存空间中(contiguous memory space),而不是指所读取的数据块是连续的。该wait event可能在以下情景中发生:

最为常见的是执行计划中包含了INDEX FULL SCAN/UNIQUE SCAN,此时出现”db file sequential read”等待是预料之中的,一般不需要我们去特别关注 当执行计划包含了INDEX RANGE SCAN-(“TABLE ACCESS BY INDEX ROWID”/”DELETE”/”UPDATE”), 服务进程将按照”访问索引->找到rowid->访问rowid指定的表数据块并执行必要的操作”顺序访问index和table,每次物理 读取都会进入”db file sequential read”等待,且每次读取的都是一个数据块;这种情况下clustering_factor将发挥其作用,需要我们特别去关注,本例中提及的解决方法对 这种情景也有效 Extent boundary,假设一个Extent区间中有33个数据块,而一次”db file scattered read”多块读所读取的块数为8,那么在读取这个区间时经过4次多块读取后,还剩下一个数据块,但是请记住多块读scattered read是不能跨越一个区间的(span an extent),此时就会单块读取并出现”db file sequential read”。这是一种正常现象,一般不需要额外关注 假设某个区间内有8个数据块,它们可以是块a,b,c,d,e,f,g,h,恰好当前系统中除了d块外的其他数据块都已经被缓存在buffer cache中了,而这时候恰好要访问这个区间中的数据,那么此时就会单块读取d这个数据块,并出现”db file sequential read”等待。注意这种情况不仅于表,也可能发生在索引上。这是一种正常现象,一般不需要额外关注 chained/migrated rows即链式或迁移行,这里我们不介绍链式行的形成原因,chained/migrated rows会造成服务进程在fetch一行记录时需要额外地单块读取,从而出现”db . . . → Read More: 何时会发生db file sequential read等待事件?

[转]BUFFER SORT是BUFFER却不是SORT

用AUTOTRACE查看执行的计划的同学常问到执行计划里的BUFFER SORT是什么意思,这里为什么要排序呢?

BUFFER SORT不是一种排序,而是一种临时表的创建方式。

BUFFER是执行计划想要表达的重点,是其操作: 在内存中存放一张临时表。

SORT修饰BUFFER,表示具体在内存的什么地方存放临时表: 在PGA的SQL工作区里的排序区。

至少有一种方法可以说服对此表示怀疑的人们,就是查询V$SQL_PLAN_STATISTICS_ALL.PROJECTION字段。

将STATISTICS_LEVEL设置为ALL先,然后执行真-排序命令,比如:select hire_date,salary from hr.employees order by hire_date

然后查看其V$SQL_PLAN_STATISTICS_ALL.PROJECTION字段:

SYS@br//scripts> select projection from v$sql_plan_statistics_all where sql_id=(select sql_id from v$sql where sql_text=’select hire_date,salary from hr.employees order by hire_date’) and operation=’SORT’ and options=’ORDER BY’; PROJECTION —————————————————————- (#keys=1) “HIRE_DATE”[DATE,7], “SALARY”[NUMBER,22] 1 row selected. 其中开头的#keys表示返回的结果中排序的字段数量。 再执行一句真-排序命令:select hire_date,salary from hr.employees order by . . . → Read More: [转]BUFFER SORT是BUFFER却不是SORT

SQL调优:Clustering Factor影响数据删除速度一例

事情是这样的,客户有一套核心的10g业务数据库,需要针对个别大表删除2年前的归档数据,这些表都是普通的堆表(heap table),没有使用分区或其他技术。因为考虑到不能影响在线业务,所以不能使用insert append/rename的方式来加速删除,只能老老实实地在匿名PL/SQL块里通过rowid批量删除数据,虽然慢一些但还是能接受的,具体的PL/SQL块如下:

DECLARE CURSOR table_name_cur IS SELECT /*+ FULL(a) */ a.rowid from table_name a where time_column<required_date table_name_rec table_name_cur%ROWTYPE; row_number number; BEGIN row_number :=0; OPEN table_name_cur; LOOP FETCH table_name_cur INTO table_name_rec; IF table_name_cur%NOTFOUND THEN commit; EXIT; END IF; delete from table_name WHERE rowid = table_name_rec.rowid; row_number := row_number + 1; if (mod (row_number,1000) =0) then . . . → Read More: SQL调优:Clustering Factor影响数据删除速度一例