2. 优化慢的SQL
既然我们已经把执行的又慢又多的SQL语句找到了,就马上开始SQL优化之旅吧。
SQL优化首先我们得会看SQL的执行计划,DM中查看SQL执行计划非常简单,在SQL的前面加EXPLAIN关键字即可,如下:
explain select * from sysobjects where subtype$='UTAB'; 1 #NSET2: [8, 1465, 3405] 2 #PRJT2: [8, 1465, 3405]; exp_num(17), is_atom(FALSE) 3 #SLCT2: [8, 1465, 3405]; SYSOBJECTS.SUBTYPE$ = UTAB 4 #CSCN2: [8, 7328, 3405]; SYSINDEXSYSOBJECTS(SYSOBJECTS as SYSOBJECTS)
--从计划可以看出,这是一个对SYSOBJECTS表的全表扫描,过滤条件是SYSOBJECTS.SUBTYPE$ = UTAB
--DM查询计划中各操作符详细的说明请参考下面这个帖子:http://www.itpub.net/forum.php?mod=viewthread&tid=173512。
另外,我们还需知道DM中如何找到SQL执行计划中各操作符的实际执行时间,如果知道了计划中各操作符的实际执行时间,那么我们就可以对慢的操作符进行针对性的优化。
首先我们需要修改dm.ini,修改一个参数,记录SQL执行时各操作符的实际执行时间,修改完成后需要重启数据库服务才能生效。
ENABLE_MONITOR = 3
然后我们创建一个存储过程,查询一些动态性能视图,获取我们需要的信息:
create or replace procedure sql_et(eid int) is begin select name as "OP", time_used/1000 || 'ms' as "TIME", cast(time_used * 100.0/sum(time_used) over() as dec(10, 2)) || '%' as "PERCENT", rank() over (order by time_used desc) as "RANK" , seq_no as "SEQ" from v$sql_node_history a, v$sql_node_name b where a.type$ = b.type$ and exec_id = eid order by time_used desc; End;
准备工作做完了,下面我们就构造一个简单的例子来实际操作一下。
--创建表
Create table tx(id int, name varchar(100)); Create table ty(id int, name varchar(100)); --Create index txl01 on tx(id); --Create index tyl01 on ty(id);