📄 第十二章 pl-sql应用程序性能调优 - pl-sql用户指南与参考 - whatiswhat.htm
字号:
<TBODY>
<TR>
<TD></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<SCRIPT language=javascript>function $(s){return document.getElementById(s);}function ShowHideDiv(divid,iImg){if($(divid).style.display == "none"){iImg.src="../../templates/newgreen/images/dot2.gif";$(divid).style.display = "block";iImg.title="收起";}else{iImg.src="../../templates/newgreen/images/dot4.gif";$(divid).style.display = "none";iImg.title="展开";}}navHover();</SCRIPT>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#111111 cellSpacing=0
cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD height=3></TD></TR></TBODY></TABLE><BR>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#111111 cellSpacing=0
cellPadding=0 width="90%" align=center border=0>
<TBODY>
<TR>
<TD width=18 height=28><IMG alt=""
src="第十二章 PL-SQL应用程序性能调优 - PL-SQL用户指南与参考 - whatiswhat.files/bg_art_left_top.gif"
border=0></TD>
<TD
background="第十二章 PL-SQL应用程序性能调优 - PL-SQL用户指南与参考 - whatiswhat.files/bg_art_top.gif">
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"></P></TD>
<TD width=18 height=28><IMG alt=""
src="第十二章 PL-SQL应用程序性能调优 - PL-SQL用户指南与参考 - whatiswhat.files/bg_art_right_top.gif"
border=0></TD></TR>
<TR>
<TD width=18
background="第十二章 PL-SQL应用程序性能调优 - PL-SQL用户指南与参考 - whatiswhat.files/bg_art_left.gif"></TD>
<TD align=middle bgColor=#f5fdee><BR><FONT style="FONT-SIZE: 14pt"
color=#295200><B>第十二章 PL/SQL应用程序性能调优</B></FONT>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#a5bd6b cellSpacing=1
cellPadding=0 width="100%" border=1>
<TBODY>
<TR>
<TD align=middle>
<TABLE style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word"
cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD align=middle>
<TABLE
style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word"
cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<DIV id=art style="MARGIN: 15px">
<CENTER><IMG alt=""
src="第十二章 PL-SQL应用程序性能调优 - PL-SQL用户指南与参考 - whatiswhat.files/o_cover.jpg"><BR><IMG
alt=""
src="第十二章 PL-SQL应用程序性能调优 - PL-SQL用户指南与参考 - whatiswhat.files/o_banner.gif">
</CENTER>
<DIV id=chapter>第十二章 PL/SQL应用程序性能调优</DIV><!-- InstanceEndEditable --><!-- InstanceBeginEditable name="EditRegion2" -->
<DIV id=text>
<P class=title1>一、PL/SQL性能问题的原由</P>
<P>当基于PL/SQL的应用程序执行效率低下时,通常是由于糟糕的SQL语句、编程方法,对PL/SQL基础掌握不好或是滥用共享内存造成的。
</P>
<UL>
<LI>PL/SQL中糟糕的SQL语句 </LI></UL>
<P>PL/SQL编程看起来相对比较简单,因为它们的复杂内容都隐藏在SQL语句中,SQL语句常常分担大量的工作。这就是为什么糟糕的SQL语句是执行效率低下的主要原因了。如果一个程序中包含很多糟糕的SQL语句,那么,无论PL/SQL语句写的有多么好都是无济于事的。
</P>
<P>如果SQL语句降低了我们的程序速度的话,就要按下面列表中的方法分析一下它们的执行计划和性能,然后重新编写SQL语句。例如,查询优化器的提示就可能会排除掉问题,如没有必要的全表扫描。
</P>
<OL>
<LI>EXPLAIN PLAN语句
<LI>使用TKPROF的SQL Trace功能
<LI>Oracle Trace功能 </LI></OL>
<UL>
<LI>不好的编程习惯 </LI></UL>
<P>通常,不好的编程习惯也会给程序带来负面影响。这种情况下,即使是有经验的程序员写出的代码也可能妨碍性能发挥。
</P>
<P>对于给定的一项任务,无论所选的程序语言有多么合适,编写质量较差的子程序(例如,一个很慢的分类或检索函数)可能毁掉整个性能。假设有一个需要被应用程序频繁调用的查询函数,如果这个函数不是使用哈希或二分法,而是直接使用线性查找,就会大大影响效率。不好的程序指的是那些含有从未使用过的变量的,传递没有必要的参数的,把初始化或计算放到不必要的循环中执行的程序等等。
</P>
<UL>
<LI>内置函数的重复 </LI></UL>
<P>PL/SQL提供了许多高度优化过的函数,如REPLACE、TRANSLATE、SUBSTR、INSTR、RPAD和LTRIM等。不要手工编写我们自己的版本,因为内置函数已经是很高效的了。即使内置函数的功能远远超过我们的需要,也不要手工实现它们功能的子集。
</P>
<UL>
<LI>低效的流程控制语句 </LI></UL>
<P>在计算逻辑表达式值的时候,PL/SQL使用短路的计算方式。也就是说,一旦结果可以被确定下来,PL/SQL就会停止剩余的表达式计算。例如,下面的OR表达式,当sal比1500小的时候,操作符左面的值就是TRUE,所以PL/SQL就不会再计算操作符右边表达式的值:
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>IF</STRONG> (sal < 1500) <STRONG>OR</STRONG> (comm <STRONG>IS</STRONG> <STRONG>NULL</STRONG>) <STRONG>THEN</STRONG><BR> ...<BR><STRONG>END</STRONG> <STRONG>IF</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>现在,思考下面的AND表达式: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>IF</STRONG> credit_ok(cust_id) <STRONG>AND</STRONG> (loan < 5000) <STRONG>THEN</STRONG><BR> ...<BR><STRONG>END</STRONG> <STRONG>IF</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>在上面的函数中,布尔函数credit_ok总是被调用。但是,如果我们向下面这样调换两个表达式的位置:
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>IF</STRONG> (loan < 5000) <STRONG>AND</STRONG> credit_ok(cust_id) <STRONG>THEN</STRONG><BR> ...<BR><STRONG>END</STRONG> <STRONG>IF</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>那么,函数只有在表达式loan <
5000的值为TRUE的时候才会被调用,这种情况也适用于EXIT-WHEN语句。 </P>
<UL>
<LI>隐式的数据类型转换 </LI></UL>
<P>运行时,PL/SQL能把结构化不同的数据类型进行隐式的转换。比如说,把PLS_INTEGER变量赋给一个NUMBER变量,由于它们的内在表现形式不一样,所以就会引起隐式地数据类型转换。
</P>
<P>避免隐式的类型转换可以改善性能。如下面的例子,15是一个有符号的4字节数字,在加法运算之前,PL/SQL必须把它转换成Oracle的数字类型。但是,浮点数15.0使用22字节的Oracle数字表现,所以就没有必要进行转换。
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>DECLARE</STRONG><BR> n <STRONG>NUMBER</STRONG>;<BR> c <STRONG>CHAR</STRONG>(5);<BR><STRONG>BEGIN</STRONG><BR> n := n + 15; <EM>-- converted</EM><BR> n := n + 15.0; <EM>-- not converted</EM><BR> ...<BR><STRONG>END</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>这里还有一个例子: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>DECLARE</STRONG><BR> c <STRONG>CHAR</STRONG>(5);<BR><STRONG>BEGIN</STRONG><BR> c := 25; <EM>-- converted</EM><BR> c := <EM>'25'</EM>; <EM>-- not converted</EM><BR> ...<BR><STRONG>END</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<UL>
<LI>不适当的数字类型声明 </LI></UL>
<P>数据类型NUMBER和它的子类型都是22字节,数据库格式的数字,它们便于移植并且能适应于不同的长度与精度。当我们需要声明一个整型变量时,就要使用PLS_INTEGER,它是最高效的数字类型。这是因为PLS_INTEGER所需的内存要比INTEGER和NUMBER类型要少。同样,
PLS_INTEGER使用机器运算,所以它的运算速度要比BINARY_INTEGER、INTEGER或NUMBER快得多。
</P>
<P>此外,INTEGER、NATURAL、NATURALN、POSITIVE、POSITIVEN和SIGNTYPE都是受约束的子类型。所以,它们的变量需要在运行时检查精度,这就会影响到效率。
</P>
<UL>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -