PLSQL Developer 70 用户指南 58.docx
《PLSQL Developer 70 用户指南 58.docx》由会员分享,可在线阅读,更多相关《PLSQL Developer 70 用户指南 58.docx(48页珍藏版)》请在冰豆网上搜索。
PLSQLDeveloper70用户指南58
5.优化
要优化你程序单元里的SQL语句,Oracle的解释计划工具能对显示语句的运行路径有很大的帮助,因此它被集成在PL/SQLDeveloper的IDE里。
要查看SQL语句或PL/SQL程序单元实际源的使用情况,PL/SQLDeveloper能够显示关于它运行情况的统计表。
你可以配置你希望显示的统计表,并且能包括耗时、CPU时间、逻辑读、物理读、物理写等等。
要确定每一个单独的PL/SQL代码行的运行时间,你可以使用PL/SQL概览图。
这个特性对于Oracle8.0或更早版本是不可用的。
最后,通过激活SQL跟踪,你可以使用Oracle的tkprof工具来获得程序单元里关于所有已运行的SQL语句的资源的使用信息。
5.1使用解释计划窗口
要使用Oracle的解释计划工具,请按工具栏里的新建按钮,选择解释计划窗口。
此时一个空的解释计划窗口就显示出来了。
在窗口的上半部,你可以键入你希望分析的SQL语句。
在按了工具栏里的执行按钮后,运行计划就被显示在窗口的下半部:
你现在可以改变SQL语句,再按执行按钮看看这个改变的效果。
要了解关于解释计划的更多信息,你可以阅读Oracle服务器调整手册。
要看查询计划里各种优化器目标的效果,请选择优化器目标列表里相应的条目,这个计划将立即被更新到反映这些改变上。
使用第一个、下一个、上一个和最近操作按钮操纵查询计划的操作顺序。
计划已经被确定后,第一个操作将高亮显示。
解释计划工具使用所谓的计划表来储存运行计划。
如果这个表对当前用户不可用,PL/SQLDeveloper将问你是否要在当前用户的计划里创建这个表。
要定义哪几个列来自于你要看的计划表,是什么顺序,请按首选项按钮,这将调出首选项页(请看第16.21章)。
注:
如果你用的是Oracle服务器7.2或更早版本,耗费与基数在计划表里不可用。
如果你用的是Oracle服务器7.3或更高版本而耗费与基数不被显示,你大概需要更新计划表。
如果你右击对象名列,这将为已选对象调出弹出式菜单。
在程序单元里分析SQL语句
大多数时间里,你希望分析的SQL语句都被包含在程序单元的源里。
要做这个,你可以选择程序编辑器里的SQL语句并且选择来自于帮助菜单的解释计划(或按F5),一个新的解释计划窗口将为已选的SQL语句创建,而且所有的PL/SQL变量就会被绑定变量替换掉。
如果你明确地复制和粘贴一个来自于程序单元包含PL/SQL变量的SQL语句并且执行解释计划窗口,你会收到一个"ORA-00904:
列名无效"的错误,解释计划工具错误地把这些变量都当成了列,因此每一个变量都必须加上一个冒号前缀。
如果我们已经要求分析employee.deptname函数里的SQL语句,则result与p_empno变量肯定会按如下被改变:
现在解释计划工具知道了哪一个标识符是列、哪个标识符是PL/SQL变量。
5.2自动统计
当你在SQL窗口或者测试窗口执行语句时,PL/SQLDeveloper将自动地生成一个此执行的统计报告。
有一个条件是你必须在动态性能表v$session,、v$statname与v$sesstat里有select权限(这些表通过标准的plustrace角色提供)。
你可以通过改变到SQL窗口或测试窗口顶部的统计表标签来查看统计报告。
用于employee.deptname函数运行的统计表可能显示如下:
对于每一个统计值,你可以看到最近运行的值和当前会话的合计。
你可以通过设置首选项来配置统计表是否被显示或者哪一个值被显示,如第16.2章里所描述的那样。
统计表的默认设置与你的SQL和PL/SQL有关,如这儿所描述:
统计值
含义
CPUusedbythis
CPU的使用(以百分之一秒为单位计)
Physicalreads
从磁盘读出的块数
Physicalwrites
写到磁盘的块数
sessionlogical
从块缓冲区或磁盘里读出的块数
sorts(disk)
在临时段里被运行的排序数量
sorts(memory)
在内存里被运行的排序数量
sorts(rows)
被排序的行数
tablefetchbyrowid
按rowid获取的行数,通常为索引访问的结果
tablescanblocks
为全表扫描读的块数
tablescanrows
为全表扫描读的行数
tablescans(long
在长表里全表扫描的数量
tablescans(short
在短表里全表扫描的数量
在测试窗口里,概览图是容易访问的。
在运行测试脚本前,简单地按测试窗口工具栏里的创建概览图报告按钮就可以了。
如果你随后运行脚本,你可以转到概览图页查看运行报告。
下面的实例报告显示了在employee.deptname函数里select语句用时149毫秒,3个dbms_output调用用时57毫秒:
在默认情况下,概览图页将显示最近运行的报告。
你也可以从运行列表里选择以前的运行。
单元列表允许你放大一个运行的特定的程序单元。
合计时间列显示了一个与行相关的时间的图形化描述,这个图形是与最多时间来做比较的,这允许你快速确定最费时间的行。
报告可以通过按列标题里的排序按钮来排序。
如果源行显示为红色,这意味着自概览图被创建以后程序单元已经被改变,因此现在代码被显示的行跟概览图被创建的时候比是不一样的。
通过按首选项按钮,你可以把概览图报告改变成不同的版面外观,这将调出相应的首选项页,如第16.6章里所述。
关于PL/SQL概览图的更多信息,请看在“Oracle8i应用包参考”手册里的dbms_profiler。
注:
不是所有平台都能提供精确的时间信息。
5.4SQL跟踪
你可以通过按工具栏里的SQL跟踪按钮来激活SQL跟踪,此后所有的由SQL窗口或测试窗口而来的服务器进程都将被登录到数据库服务器上的跟踪文件里。
有一个前提条件是,你正在使用的数据库实例的定时统计的参数必须被设成True。
你可以通过再一次按SQL跟踪按钮来禁止SQL跟踪。
你可以通过使用数据库服务器上的Oracletkprof工具来查看跟踪文件里的信息,它将为每一个SQL语句产生一个关于耗时、CPU时间、I/O等等的报告,因此它能使你知道程序单元里哪一个语句最耗时间。
要学习更多关于Oracletkprof的知识,你可以读一读“Oracle7服务器调整”手册。
运行employee.deptname函数的tkprof报告可以显示如下:
TKPROF:
Release7.2.2.3.1-ProductiononFriSep2614:
59:
081997
Copyright(c)OracleCorporation1979,1994.Allrightsreserved.
Tracefile:
ora07087.trc
Sortoptions:
default
********************************************************************************
count=numberoftimesOCIprocedurewasexecuted
cpu=cputimeinsecondsexecuting
elapsed=elapsedtimeinsecondsexecuting
disk=numberofphysicalreadsofbuffersfromdisk
query=numberofbuffersgottenforconsistentread
current=numberofbuffersgottenincurrentmode(usuallyforupdate)
rows=numberofrowsprocessedbythefetchorexecutecall
********************************************************************************
begin
:
deptname:
=employee.deptname(:
empno);
end;
callcountcpuelapseddiskquerycurrentrows
-----------------------------------------------------------------------
Parse10.000.000000
Execute10.010.010001
Fetch00.000.000000
-----------------------------------------------------------------------
total20.010.010001
Missesinlibrarycacheduringparse:
0
Optimizerhint:
CHOOSE
Parsinguserid:
16
********************************************************************************
SELECTDEPT.DNAME
FROM
DEPT,EMPWHEREEMP.EMPNO=:
b1ANDDEPT.DEPTNO=EMP.DEPTNO
callcountcpuelapseddiskquerycurrentrows
-----------------------------------------------------------------------
Parse10.000.000000
Execute10.000.000005
Fetch10.060.064401
-----------------------------------------------------------------------
total30.060.064406
Missesinlibrarycacheduringparse:
0
Optimizerhint:
CHOOSE
Parsinguserid:
16(recursivedepth:
1)
6.专用SQL
在程序开发期间,你经常需要运行一些SQL语句。
既要测试语句,又要查看或者更新表里的数据。
你可以在PL/SQLDeveloper内部通过使用SQL窗口就能做好这件事。
6.1使用SQL窗口
要创建一个新的SQL窗口,请按工具栏里的新建按钮,再选择SQL窗口,一个空的SQL窗口就显示出来了。
在这个窗口里,你可以键入SQL语句。
如果它是select语句,窗口会分成两部分,下半部分是显示结果的表格。
如果我们要查看雇员表里的所有雇员,SQL窗口将显示如下:
SQL语句被运行,10行数据被提取。
若结果集大于10行,可以通过按结果集工具栏里的获取下一页和获取最后页两个按钮来显示结果集,并且(更多...)被显示在状态行上。
最初只有10行被获取,这是因为能被显示在表格里的记录数只有这些。
按获取下一页按钮将获取下一个10行数据,等等。
按获取最后页按钮将获取所有行。
如果你在SQL编辑器里有若干个SQL语句并且按了执行按钮,所有的语句都将被执行,结果将在不同的标签页里被显示出来:
SQL语句必须用分号(;)或者斜杠(/)来终止,PL/SQL块必须用斜杠(/)来终止,这几乎与SQL*Plus一样。
如果你选择了一个结果标签,那么SQL编辑器里相应的文本就会被高亮显示。
如果你选择了SQL编辑器里文本的一部分,那么仅仅被选择的文本将被运行。
这样,你可以在编辑器里有多于一个的语句,仍然可以一个一个地运行它们。
如果你运行SQL语句要花很长时间才能完成,你可以按中断按钮来终止它。
注意按中断按钮并不总是成功的。
例如,如果语句正在等待锁,它将不响应中断信号。
如果你在SQL窗口正在获取行的时候按了中断按钮,它将简单地停止并显示已经被获取的行,你现在可以用获取下一页和获取最后页来继续获取记录。
注意,SQL窗口首选项允许你确定一个select语句最初可以获取多少行,这在第16.19章里有描述。
在窗口的右边你可以看到两个按钮,它们会允许你操纵已经输入进SQL窗口里的所有SQL语句,这样你可以快速地再运行预先输入的语句。
为了优化目的,你可以通过选择统计表标签来查看SQL语句运行情况的统计表。
统计表在第5.2章里有解释。
当你打印SQL窗口时,SQL语句和结果表格都将被打印。
通过选择结果表格里的行,你可以限制将要打印的行的数量。
6.2结果表格处理
SQL窗口的结果表格可以用不同的方法来处理。
一些单元格类型有特殊的行为,行、列和单元格排列都能被选择和打印,列可以被移动,行可以被排序,你可以转到单一的记录来查看,等等。
识别null值
Null值被显示于一个浅黄色背景的单元格里,所以你可以快速地从全是空格的值里区别出它们。
这对识别null值和在单元格里不直接显示的值也是有用的,如long值和LOB值。
你可以通过首选项来改变null值单元格的颜色(请看第16.19章)。
查看大数据列
Long、LongRaw、CLOB、BLOB与BFILE列的值不直接在结果表格里显示,表格里只是简单地显示为、、、和:
当你点击某一列的单元格按钮时,大数据编辑器就被调出来了,它允许你查看或编辑不同格式的数据。
更多细节请看第19章。
你也可以点击字符列上的单元格按钮来调用大数据编辑器,不过单元格按钮仅存在于大于20个字符的列。
查看日期列
日期列有一个显示日历的单元格按钮,这个日历的当前日期为高亮显示。
如果日期还有时间部分,你可以在日历上这样查看它的值:
查看时间戳列
时间戳列被显示在指定的格式里,这个格式在你的Oracle主目录的NLS_TIMESTAMP_FORMAT和NLS_TIMESTAMP_TZ_FORMAT的注册表设置里被指定。
查看XML数据
在数据库里储存XML数据有多种情形,都可以储存为:
CLOB(Oracle8i)、XMLTYPE(Oracle9i)或者甚至Varchar2、Long列。
只要XML格式是以标准的XML标题开始,大数据编辑器无论如何都能识别出它并且转入XML格式。
要了解更多的详细资料,请看第19章。
查看嵌套游标列
如果你在select语句的字段列表里包含了嵌套游标,最初列值将被显示为。
按单元格按钮将调出新的SQL窗口,它带有一个有游标结果集的结果表格,这可以用于查看简单的嵌套查询。
注意每一个嵌套游标都将在暗中造成一个打开的游标,因此对于大的结果集,你能容易地陷入OPEN_CURSORS的限制,并且得到“ORA-01000:
打开游标超越最大限制”的错误。
选择行、列与单元格
要在结果表格里选择行或列,只需点行标题或列标题并且拖动鼠标指针直到要选择的区域高亮显示即可:
现在,选择的列可以通过释放鼠标按钮来移动了。
再点已选列的标题中的一个,就可以拖动已选列到新的地方了。
要选择一个特定范围的单元格,移动鼠标指针越过一个单元格的左边直到光标形态改变,再按鼠标按钮,拖动鼠标直到要选择的区域高亮显示:
要选择所有的行与列,请按左上角的单元格,或者右击表格并选择来自于弹出式菜单的全选项目。
已选择的高亮区域通常都能被复制或打印。
导出数据
有几个方法可以导出结果集表格里的数据。
运行了select语句后,你可以采用如上面所述的方法选择一定范围的单元格,右击它,在从弹出式菜单上选择导出结果项
目。
这将显示出一个子菜单,在这里你可以选定导出数据到CSV格式(逗号分隔值)、TSV格式(制表符分隔值)、HTML格式或者XML格式。
选择了格式后,你就能指定导出文件了。
作为选择,通过按Ctrl-C,或者通过右击你选择的数据并且选择来自于弹出式菜单上的复制或带标题复制项目,你就可以把你选择的数据复制到剪贴板上。
随后,你可以把这些数据粘贴到另外的应用程序里,例如电子表格、文字处理软件等等。
要在MicrosoftExcel里快速地操作这些结果集信息,就选择复制到Excel项目,这将打开一个新的Excel实例,并且所有已选择的数据也将被复制过去。
给行排序
要在结果表格里给行排序,请按你要排序的列的标题按钮:
按一次标题按钮,行被排成升序;再按一次标题按钮,行被排成降序;按第三次,行将撤消排序。
按另一个列的标题按钮将对这个列所在的行进行排序,但也将使用先前的排序列为第二排序列(标题按钮上显示为一个圆点)。
在上面的例子里,列job是第一排序列,列hiredate为第二排序列。
注意排序是在本地被运行的,并且仅仅是已经获取的行的排序。
如果你在对结果排序后又获取了另外一些行,这些新行将被添加到结果表格的末尾,并不排序。
对于大的结果集,本地排序能花很长时间。
在这种情况下,最好能在select语句里使用orderby子句,让Oracle服务器来排序。
单个记录查看
如果结果集包含很多列,每条记录都显示在一行上也许是不方便的,你必须前后滚读相关的列(尽管你可以移动列),不能马上看到记录的所有的列。
通过按表格工具栏里的单个记录查看按钮,你就能一次查看一个单个记录了:
现在每行显示一个列名和值。
表格工具栏里的下一个记录和上一个记录能被用于操纵结果集。
要转回到多记录查看,就再按一次单个记录查看按钮。
6.3实例模式查询
运行了select语句后,如果你要搜索特定的记录,你可以按结果集上方的实例查询按钮。
按这个按钮将清除表格,只剩下一个空记录,在这里你可以输入你的查询值。
例如,如果你要查找部门编码为20的、以字母A打头的所有的雇员,就在列ename里输入A%并且在deptno列里输入20即可:
再按实例查询按钮,或按执行按钮,将运行已修改的查询,并显示被限定的结果。
再按实例查询按钮,前面的查询值仍然被保留。
按清除记录按钮就可以清除查询值了。
查询值不限制带有通配符的单一值,你可以使用下列表达式(也可以选择方括号里的表达式):
•值[=值]
•带有通配符的值[like带有通配符的值]
•>值
•!
=值[<>值]
•in(值1,值2,...)
•between值1and值2
•null[isnull]
•notnull[isnotnull]
注意,如果你使用了文字值,你可以省略字符值的引号(例如,在SQL文本里,SMITH将自动地被转换成‘SMITH’)。
对于所有其它表达式,你必须提供Oracle服务器懂得的文字值(例如,!
=’SMITH’)。
对于数字和日期值,也是这种情形。
如果你要在表达式里使用它,就必须使用Oracle服务器懂得的格式。
有几个首选项允许你控制实例查询功能的默认行为(例如,区分大小写),第16.19章描述了这几个首选项。
6.4连接查询
当查看一个结果集时,你经常要查询相关表。
例如,当你查看dept表时,你也许要查询一个部门里的所有雇员,或者反之亦然:
当你查看emp表时,你也许要查询一个雇员所在的部门。
多数情况下,这些父表与子表之间有外键约束,这时SQL窗口能够自动地为你生成和运行这些查询。
如果你确定了结果集里一条特定记录的位置,按表格工具栏里的连接查询按钮,这将显示出一个弹出式菜单,里面包含了当前select语句的表的所有父表和子表。
例如,如果你在查询表emp,则下面的弹出式菜单将显示出来:
上面部分显示出了父表(和外键名),下面部分显示了子表。
项目dept将为这个雇员的部门(30)生成一个查询,第一个emp项目(父表里的)将为这个雇员的经理(7839)生成一个查询,第二个emp项目(子表里的)将为被这个雇员管理的所有雇员生成一个查询。
连接查询将在同样的SQL窗口里被运行,除非你使SQL窗口首选项在新窗口里执行连接查询(参看第16.19章)。
当你按住连接查询按钮同时再按Ctrl键时,这个首选项将反向发生。
6.5置换变量
当查询被运行时,你可以在你的SQL文本里使用置换变量以允许用户输入数据。
置换变量的最简单形式类似于你也许习惯使用的SQL*Plus:
通过指定SQL文本里的&deptno,你将被提示为这个变量输入一个值。
在运行前,SQL文本里的变量参照将被置换成这个输入值。
你可以指定不止一个的置换变量,而且你可以不止一次地指定一个单一的置换变量。
此外,你还可以定义数据类型、默认值、选择列表、列表查询、检验栏等其它高级选项。
这些特性也被用于报告窗口,详细情况在第10章里有描述。
6.6更新数据库
要更新、插入或删除数据库里的记录,你可以在SQL窗口里运行适当的DML语句。
通过将rowid包括在选择列表里或者使用select...forupdate语句,使结果表格可以更新,这大概对我们是更加方便的:
你应该意识到,一个select...forupdate语句将锁住所有已选的记录,所以一般来说包括rowid可能是一种使结果集可更新的最好的方法。
如果select语句是一个内部联接,则第一个表的列就能被更新,所有的其它列都是只读,有别名的列也不能被更新。
如果结果表格是可更新的,你可以按结果表格右边的编辑数据按钮来编辑记录,你可以通过按插入记录或删除记录按钮来插入或删除表格里的记录。
如果你已经选择了多条记录,所有被选择的记录都会被删除。
实际上修改结果表格不会改变数据库里的任何东西。
要记入已经更新、插入或删除的记录到数据库里,请按记入改变按钮。
如果你禁止了自动提交SQL窗口的选项,则如果事务已经被开始,工具栏里的提交和回滚按钮就会被激活。
要了解更多关于事务的信息,请看第14章。
编辑大数据列
与前面一章解释的一样,你可以点击Long、LongRaw、CLOB、BLOB和B