Oracle技巧实录
- 格式:doc
- 大小:56.50 KB
- 文档页数:7
ORACLE存储过程详解教程ORACLE存储过程是一种预先编译的数据库对象,它包含了一组执行特定任务的SQL语句和程序逻辑。
存储过程可以在数据库中存储并被多个客户端应用程序调用,从而提高应用程序的性能和安全性。
在本篇文章中,我们将详细介绍ORACLE存储过程的概念、语法和使用方法。
一、存储过程的概念存储过程是一段预定义的SQL代码块,它可以接受参数并可选地返回结果。
存储过程在执行时可以访问数据库对象并执行事务处理。
存储过程可以被调用多次,减少了代码的编写和重复性的执行。
存储过程具有以下特点:1.存储过程是预先编译的,因此执行速度比动态SQL语句更快。
2.存储过程可以接受输入参数,并可以在参数基础上进行一系列的SQL操作。
3.存储过程可以返回一个或多个结果集。
4.存储过程可以包含条件判断、循环和异常处理等控制结构。
二、存储过程的语法创建存储过程的语法如下:CREATE [OR REPLACE] PROCEDURE procedure_name[ (parameter_name [IN,OUT] datatype [, ...]) ]IS[local_variable_declarations]BEGIN[executable_statements]EXCEPTION[exception_handling_statements]END;存储过程的语法包含以下几个部分:1.CREATE[ORREPLACE]PROCEDURE:指定创建一个存储过程。
CREATE关键字用于创建新的存储过程,而ORREPLACE关键字用于替换已存在的同名存储过程。
2. procedure_name:指定创建的存储过程的名称。
3. (parameter_name [IN,OUT] datatype[, ...]):指定存储过程的输入和输出参数。
参数的名称和数据类型必须指定,并且可以指定IN或OUT关键字来表示参数的传入和传出。
Sql*plus中蕴藏着好多技巧,如果掌握这些技巧,对于在oracle数据库下进行快速开发与有效维护数据库都是有益的。
1.使用SQL*PLUS动态生成批量脚本将spool与select命令结合起来使用,可以生成一个脚本,脚本中包含有可以批量执行某一任务的语句。
例1:生成一个脚本,删除SCOTT用户下的所有的表:a. 创建gen_drop_table.sql文件,包含如下语句:SPOOL c:\drop_table.sqlSELECT 'DROP TABLE '|| table_name ||';' FROM user_tables;SPOOL OFFb. 以SCOTT用户登录数据库SQLPLUS > @ …..\gen_dorp_table.sqlc. 在c盘根目录下会生成文件drop_table.sql文件,包含删除所有表的语句,如下所示:SQL>SELECT 'DROP TABLE '|| table_name ||';' FROM user_tables;'DROPTABLE'||TABLE_NAME||';'------------------------------------DROP TABLE DEPT;DROP TABLE EMP;DROP TABLE PARENT;DROP TABLE STA T_VENDER_TEMP;DROP TABLE TABLE_FORUM;5 rows selected.SQL>SPOOL OFFd. 对生成的drop_table.sql文件进行编辑去掉不必要的部分,只留下drop table …..语句e. 在scott用户下运行dorp_table.sql文件,删除scott用户下所有的表。
SQLPLUS > @ c:\dorp_table.sql在上面的操作中,在生成的脚本文件中会有多余的字符,如运行的sql语句,标题,或返回的行数,需要我们编辑该脚本后再运行,给实际的操作带来诸多不便。
Oracle百万数据查询优化技巧三十则Oracle百万数据查询优化技巧三十则1.对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及 order by涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=03.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num=10 or num=20可以这样查询:select id from t where num=10union allselect id from t where num=205.in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)对于连续的数值,能用 between 就不要用 in 了:select id from t where num between 1 and 36.下面的查询也将导致全表扫描:select id from t where name like '%abc%'若要提高效率,可以考虑全文检索。
7.如果在where 子句中使用参数,也会导致全表扫描。
因为SQL 只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。
然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。
如下面语句将进行全表扫描:select id from t where num=@num可以改为强制查询使用索引:select id from t with(index(索引名)) where num=@num 8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。
情感语录1.爱情合适就好,不要委屈将就,只要随意,彼此之间不要太大压力2.时间会把最正确的人带到你身边,在此之前,你要做的,是好好的照顾自己3.女人的眼泪是最无用的液体,但你让女人流泪说明你很无用4.总有一天,你会遇上那个人,陪你看日出,直到你的人生落幕5.最美的感动是我以为人去楼空的时候你依然在6.我莫名其妙的地笑了,原来只因为想到了你7.会离开的都是废品,能抢走的都是垃圾8.其实你不知道,如果可以,我愿意把整颗心都刻满你的名字9.女人谁不愿意青春永驻,但我愿意用来换一个疼我的你10.我们和好吧,我想和你拌嘴吵架,想闹小脾气,想为了你哭鼻子,我想你了11.如此情深,却难以启齿。
其实你若真爱一个人,内心酸涩,反而会说不出话来12.生命中有一些人与我们擦肩了,却来不及遇见;遇见了,却来不及相识;相识了,却来不及熟悉,却还要是再见13.对自己好点,因为一辈子不长;对身边的人好点,因为下辈子不一定能遇见14.世上总有一颗心在期待、呼唤着另一颗心15.离开之后,我想你不要忘记一件事:不要忘记想念我。
想念我的时候,不要忘记我也在想念你16.有一种缘分叫钟情,有一种感觉叫曾经拥有,有一种结局叫命中注定,有一种心痛叫绵绵无期17.冷战也好,委屈也罢,不管什么时候,只要你一句软话,一个微笑或者一个拥抱,我都能笑着原谅18.不要等到秋天,才说春风曾经吹过;不要等到分别,才说彼此曾经爱过19.从没想过,自己可以爱的这么卑微,卑微的只因为你的一句话就欣喜不已20.当我为你掉眼泪时,你有没有心疼过情感语录1.爱情合适就好,不要委屈将就,只要随意,彼此之间不要太大压力2.时间会把最正确的人带到你身边,在此之前,你要做的,是好好的照顾自己3.女人的眼泪是最无用的液体,但你让女人流泪说明你很无用4.总有一天,你会遇上那个人,陪你看日出,直到你的人生落幕5.最美的感动是我以为人去楼空的时候你依然在6.我莫名其妙的地笑了,原来只因为想到了你7.会离开的都是废品,能抢走的都是垃圾8.其实你不知道,如果可以,我愿意把整颗心都刻满你的名字9.女人谁不愿意青春永驻,但我愿意用来换一个疼我的你10.我们和好吧,我想和你拌嘴吵架,想闹小脾气,想为了你哭鼻子,我想你了11.如此情深,却难以启齿。
千里之行,始于足下。
Oracle数据库应用技巧
以下是一些Oracle数据库应用技巧:
1. 使用合适的数据类型:根据数据的具体需求和大小来选择合适的数据类型,以减少存储空间和提高查询效率。
2. 创建适当的索引:根据查询需求创建合适的索引,以加速数据检索操作。
同时,确保对索引进行定期维护和优化,以确保其最佳性能。
3. 使用批量操作和事务:在进行大量数据操作时,使用批量操作和事务可以提高效率和数据的一致性。
4. 使用合适的查询语句:合理使用查询语句,例如使用JOIN来优化复杂
查询,避免使用过多的子查询,并使用EXPLAIN PLAN来分析查询执行计划。
5. 执行定期维护:定期执行数据库维护任务,例如备份数据库、清理无用数据、收集统计信息等,以保证数据库的稳定性和性能。
6. 使用适当的存储布局:根据业务需求使用合适的存储布局,例如使用分区表来提高查询性能,使用表空间来管理数据库空间等。
7. 监控数据库性能:使用Oracle提供的性能监控工具,例如Enterprise Manager、AWR报告等,来监控数据库的性能并及时调整优化。
8. 使用合适的SQL优化技巧:例如使用内联视图替换复杂的子查询,使用临时表来存储中间结果,使用分析函数来处理复杂的数据分析需求等。
第1页/共2页
锲而不舍,金石可镂。
9. 合理管理内存和硬盘空间:根据数据库的实际需求,调整内存分配和硬盘空间,以确保数据库的正常运行和性能。
10. 使用合适的安全策略:配置适当的安全设置,例如限制访问权限、使用强密码、定期更新数据库软件和补丁等,以保护数据库的安全性。
oracle登录实例Oracle是一种广泛使用的关系型数据库管理系统,它提供了强大的功能和工具,可以帮助用户管理和处理大量的数据。
在本文中,我们将介绍如何登录Oracle实例。
要登录Oracle实例,我们需要打开一个命令行界面。
在Windows系统上,可以点击“开始”按钮,然后选择“运行”,输入“cmd”并按下回车键来打开命令行界面。
在Linux或Unix系统上,可以打开终端窗口。
接下来,我们需要输入登录命令来连接到Oracle实例。
登录命令的格式如下:sqlplus /nolog这个命令将打开SQL*Plus工具,它是Oracle提供的一个交互式的命令行界面,用于执行SQL语句和管理数据库。
然后,我们需要输入连接命令来连接到我们要登录的Oracle实例。
连接命令的格式如下:connect username/password@hostname:port/service_name其中,username是我们要登录的用户名,password是对应的密码,hostname是Oracle实例所在的主机名或IP地址,port是监听端口号,service_name是数据库的服务名。
例如,如果我们要登录一个用户名为scott,密码为tiger的Oracle实例,它所在的主机名为localhost,监听端口号为1521,服务名为orcl,那么连接命令应该是这样的:connect scott/tiger@localhost:1521/orcl在输入连接命令之后,我们按下回车键,系统将尝试连接到指定的Oracle实例。
如果连接成功,我们将看到一个提示符,表示我们已经成功登录到Oracle实例。
此时,我们可以开始使用SQL*Plus工具来执行各种数据库操作。
我们可以输入SQL语句来查询、插入、更新或删除数据,也可以执行数据库管理操作,如创建表、索引或视图。
除了SQL语句,SQL*Plus还提供了一些特殊命令和控制选项,可以帮助我们更好地管理和处理数据。
ORACLE优化常用技巧多表查询优化注:这里提供的是编程时SQL语句的执行性能的优化,而不是后台数据库的优化。
执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全是两个概念.单表统计可能只要0.02秒,但是2张表联合统计就可能要几十表了.这是因为ORACLE只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适用于多表连接查询..数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了.当你向ORACLE提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句.这里需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须完全相同(包括空格,换行等).共享的语句必须满足两个条件:A.字符级的比较:当前被执行的语句和共享池中的语句必须完全相同.例如:SELECT * FROM EMP;和下列每一个都不同SELECT * from EMP;Select * From Emp;SELECT * FROM EMP;B.两个SQL语句中必须使用相同的名字的绑定变量(bind variables)例如:第一组的两个SQL语句是相同的(可以共享),而第二组中的两个语句是不同的a.select pin , name from people where pin = :blk1.pin;select pin , name from people where pin = :blk1.pin;b.select pin , name from people where pin = :blk1.ot_ind;select pin , name from people where pin = :blk1.ov_ind;重点关注1:选择最有效率的表名顺序ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.例如: 表TAB1 16,384 条记录表TAB2 1 条记录选择TAB2作为基础表(最好的方法)select count(*) from tab1,tab2 执行时间0.96秒选择TAB2作为基础表(不佳的方法)select count(*) from tab2,tab1 执行时间26.09秒如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.例如: EMP表描述了LOCA TION表和CA TEGORY表的交集.SELECT *FROM LOCA TION L ,CA TEGORY C,EMP EWHERE E.EMP_NO BETWEEN 1000 AND 2000AND E.CA T_NO = C.CA T_NOAND E.LOCN = L.LOCN将比下列SQL更有效率SELECT *FROM EMP E ,LOCA TION L ,CA TEGORY CWHERE E.CA T_NO = C.CA T_NOAND E.LOCN = L.LOCNAND E.EMP_NO BETWEEN 1000 AND 2000重点关注2:WHERE子句中的连接顺序ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.例如:(低效,执行时间156.3秒)SELECT …FROM EMP EWHERE SAL >; 50000AND JOB = ‘MANAGER’AND 25 < (SELECT COUNT(*) FROM EMPWHERE MGR=E.EMPNO);(高效,执行时间10.6秒)SELECT …FROM EMP EWHERE 25 < (SELECT COUNT(*) FROM EMPWHERE MGR=E.EMPNO)AND SAL >; 50000AND JOB = ‘MANAGER’;重点关注3:SELECT子句中避免使用“*”当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用‘*’是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将’*’依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.减少访问数据库的次数当执行每条SQL语句时, ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量, 读数据块等等. 由此可见, 减少访问数据库的次数, 就能实际上减少ORACLE的工作量.例如,以下有三种方法可以检索出雇员号等于0342或0291的职员.方法1 (最低效)SELECT EMP_NAME , SALARY , GRADEFROM EMPWHERE EMP_NO = 342;SELECT EMP_NAME , SALARY , GRADEFROM EMPWHERE EMP_NO = 291;方法2 (次低效)DECLARECURSOR C1 (E_NO NUMBER) ISSELECT EMP_NAME,SALARY,GRADEFROM EMPWHERE EMP_NO = E_NO;BEGINOPEN C1(342);FETCH C1 INTO …,..,.. ;OPEN C1(291);FETCH C1 INTO …,..,.. ;CLOSE C1;END;方法3 (高效)SELECT A.EMP_NAME , A.SALARY , A.GRADE,B.EMP_NAME , B.SALARY , B.GRADEFROM EMP A,EMP BWHERE A.EMP_NO = 342AND B.EMP_NO = 291;注意:在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量,建议值为200.重点关注4:使用DECODE函数来减少处理时间使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表. 例如:SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0020 AND ENAME LIKE ‘SMITH%’;SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKE ‘SMITH%’;SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0020 AND ENAME LIKE ‘SMITH%’;SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKE ‘SMITH%’;可以用DECODE函数高效地得到相同结果:SELECT COUNT(DECODE(DEPT_NO,0020,’X’,NULL)) D0020_COUNT,COUNT(DECODE(DEPT_NO,0030,’X’,NULL)) D0030_COUNT,SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SALFROM EMP WHERE ENAME LIKE ‘SMITH%’;SELECT COUNT(DECODE(DEPT_NO,0020,’X’,NULL)) D0020_COUNT,COUNT(DECODE(DEPT_NO,0030,’X’,NULL)) D0030_COU NT,SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SALFROM EMP WHERE ENAME LIKE ‘SMITH%’;类似的,DECODE函数也可以运用于GROUP BY和ORDER BY子句中.重点关注5: 删除重复记录最高效的删除重复记录方法( 因为使用了ROWID)DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO);重点关注6: 用TRUNCATE替代DELETE当删除表中的记录时,在通常情况下,回滚段(rollback segments ) 用来存放可以被恢复的信息,如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况),而当运用TRUNCA TE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短.注:TRUNCA TE只在删除全表适用,TRUNCA TE是DDL不是DML重点关注7: 尽量多使用COMMIT只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:COMMIT所释放的资源:a. 回滚段上用于恢复数据的信息.b. 被程序语句获得的锁c. redo log buffer 中的空间d. ORACLE为管理上述3种资源中的内部花费注:在使用COMMIT时必须要注意到事务的完整性,现实中效率和事务完整性往往是鱼和熊掌不可得兼重点关注8:减少对表的查询在含有子查询的SQL语句中,要特别注意减少对表的查询.例如:低效SELECT TAB_NAME FROM TABLESWHERE TAB_NAME = ( SELECT TAB_NAMEFROM TAB_COLUMNSWHERE VERSION = 604)AND DB_VER= ( SELECT DB_VERFROM TAB_COLUMNSWHERE VERSION = 604)高效SELECT TAB_NAME FROM TABLESWHERE (TAB_NAME,DB_VER)= ( SELECT TAB_NAME,DB_VER)FROM TAB_COLUMNSWHERE VERSION = 604)Update 多个Column 例子:低效:UPDA TE EMPSET EMP_CA T = (SELECT MAX(CA TEGORY) FROM EMP_CA TEGORIES), SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CA TEGORIES)WHERE EMP_DEPT = 0020;高效:UPDA TE EMPSET (EMP_CA T, SAL_RANGE)= (SELECT MAX(CA TEGORY) , MAX(SAL_RANGE)FROM EMP_CA TEGORIES)WHERE EMP_DEPT = 0020;重点关注9:用EXISTS替代IN在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率.低效:SELECT * FROM EMP (基础表)WHERE EMPNO >; 0AND DEPTNO IN (SELECT DEPTNOFROM DEPTWHERE LOC = ‘MELB’)高效:SELECT * FROM EMP (基础表)WHERE EMPNO >; 0AND EXISTS(SELECT ‘X’FROM DEPTWHERE DEPT.DEPTNO = EMP.DEPTNOAND LOC = ‘MELB’)重点关注10:用NOT EXISTS替代NOT IN在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的(因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.例如:SELECT …FROM EMPWHERE DEPT_NO NOT IN (SELECT DEPT_NOFROM DEPTWHERE DEPT_CA T=’A’);为了提高效率.改写为:(方法一: 高效)SELECT ….FROM EMP A,DEPT BWHERE A.DEPT_NO = B.DEPT(+)AND B.DEPT_NO IS NULLAND B.DEPT_CA T(+) = ‘A’(方法二: 最高效)SELECT ….FROM EMP EWHERE NOT EXISTS (SELECT ‘X’FROM DEPT DWHERE D.DEPT_NO = E.DEPT_NOAND DEPT_CA T = ‘A’);当然,最高效率的方法是有表关联.直接两表关系对联的速度是最快的!重点关注11:计算记录条数和一般的观点相反, count(*) 比count(1)稍快,当然如果可以通过索引检索,对索引列的计数仍旧是最快的. 例如COUNT(EMPNO)重点关注12:用Where子句替换HA VING子句避免使用HA VING子句,HA VING 只会在检索出所有记录之后才对结果集进行过滤,这个处理需要排序、总计等操作,如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销, 例如:--低效SELECT REGION,A VG(LOG_SIZE) FROM LOCA TION GROUP BY REGION HA VING REGION != ‘SYDNEY’AND REGION != ‘PERTH’--高效SELECT REGION,A VG(LOG_SIZE) FROM LOCA TION WHERE REGION != ‘SYDNEY’AND REGION != ‘PERTH’GROUP BY REGION重点关注13:用EXISTS替换DISTINCT当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换--低效:SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO--高效:SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X’ FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);--EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.重点关注14:用索引提高效率索引是表的一个概念部分,用来提高检索数据的效率,实际上ORACLE使用了一个复杂的自平衡B-tree结构,通常通过索引查询数据比全表扫描要快,当ORACLE找出执行查询和Update语句的最佳路径时,ORACLE优化器将使用索引,同样在联结多个表时使用索引也可以提高效率,另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证,除了那些LONG或LONG RA W数据类型, 你可以索引几乎所有的列. 通常, 在大型表中使用索引特别有效. 当然,你也会发现, 在扫描小表时,使用索引同样能提高效率,虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价. 索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改,这意味着每条记录的INSERT , DELETE , UPDA TE将为此多付出4 , 5 次的磁盘I/O,因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢注:定期的重构索引是有必要的.重点关注15:避免在索引列上使用计算WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描. 举例:--低效:SELECT …FROM DEPT WHERE SAL * 12 > 25000;--高效:SELE CT … FROM DEPT WHERE SAL > 25000/12;重点关注16:用>=替代>(再次重申重点关注)--如果DEPTNO上有一个索引--高效:SELECT * FROM EMP WHERE DEPTNO >=4--低效:SELECT * FROM EMP WHERE DEPTNO >3两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录.重点关注17:识别’低效执行’的SQL语句用下列SQL工具找出低效SQL:SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,SQL_TEXTFROM V$SQLAREAWHERE EXECUTIONS>0AND BUFFER_GETS >0AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8ORDER BY 4 DESC;。
Oracle数据库一些不常见但很重要的使用技巧总结篇发布时间: 2011-7-22 10:43 作者: 鹤冲天(cnblogs) 来源: 51Testing软件测试网采编字体: 小中大|上一篇下一篇|打印|我要投稿|推荐标签:数据库OracleOracle数据库使用过程中,有一些技巧是使用过程中需要去了解和掌握的,掌握这些技巧我们在以后使用数据库的过程中就可以避免走很多弯路,提高查询效率。
本文主要介绍一下七点技巧,希望能对各位有所帮助,接下来我们就一一介绍。
使用技巧:1. procedure和function中的select后面不要跟变量,否则会极大的波及SQL效率。
2. TRUNCATE 在procedure中无法利用,可写成:3. 当运行DML(数据垄断语言,增删改查)语句时,PL/SQL敞开一个内建游标并处理收获,游标是维护查询收获的内存中的一个区域,游标在运行DML语句时敞开,告终后关闭。
隐式游标只利用SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT三个属性。
SQL%FOUND,SQL%NOTFOUND 是布尔值,SQL%ROWCOUNT是整数值。
告终循环时能够此作为退出循环的推断规范。
4. 为了不重复解析雷同的SQL语句,在第顺次解析尔后,ORACLE将SQL语句储藏在内存中。
这块位于系统大局区域SGA(system global area)的分享池(shared buffer pool)中的内存能够被所有的数据库用户分享。
因而,当你厉行一个SQL语句(有时被称为一个游标)时,万一它和之前的厉行过的语句全面雷同,ORACLE就能很快获得曾经被解析的语句以及良好的厉行路径。
分享的语句定然中意三个条件:a. 字符级的比拟:目前被厉行的语句和分享池中的语句定然全面雷同。
包括所有的空格和字母大小写。
b. 两个语句所指的对象定然全面雷同。
例如两个用户对于统一个表,一个是table owner,一个是引用同义词,那么是无法SQL分享的。
Oracle数据库移植时字符集问题的解决作者:slackerqxl对于Oracle数据库之间的移植采用Oracle的导入导出工具(Import/Export)是一个比较好的策略。
虽也可以利用第三方软件如Sybase 的Power designer中的Reverse Engineering 进行数据库结构重建,然后在进行较复杂的数据导入过程,但对于作业队列、快照等则不得不用手工来创建。
而Export能将整个数据库、指定用户、指定表和相关的数据字典进行输出,Export输出的输出转存二进制文件包括了完全重建所有被选对象所需的命令。
本人在为某电厂MIS(Oracle数据库)数据采用Oracle的导入导出工具从Windows NT平台移植到Digital Unix平台时遇到的关于字符集的问题和总结出的经验与大家来分享。
1. 移植环境原操作系统平台:Windows NT数据库:Oracle 8.0.5 for Windows NT服务器:HP NetServer LH3目标操作系统平台:Digital Unix alpha V4.0数据库:Oracle 8.0.4 for Digital Unix服务器:ALPHASERVER ES40 小型机2. 数据导出在NT服务器上用Oracle导出工具进行数据导出,Oracle导出工具有命令行和图形界面两种本人直接用命令行方式进行数据导出:c:> exp80 gxmisdba/manager file=c:expdat.dmp log=c:export.log即将导出指定的用户.... 正在导出用户GXMISDBA的外部函数程序库名称. 正在导出用户GXMISDBA的对象类型定义即将导出GXMISDBA的对象.... 正在导出数据库链接. 正在导出序号. 正在导出群集定义. 即将导出GXMISDBA的表通过常规路径.... . 正在导出表AAAAA 0 行被导出. . 正在导出表EVT_CARRIER_CONFIGURA TION 0 行被导出. . 正在导出表TBL_AJ_AGKS 331 行被导出. 正在导出同义词. 正在导出视图. 正在导出存储的过程. 正在导出参考资料一致性约束条件. 正在导出触发器. 正在导出后期表活动. 正在导出快照. 正在导出快照日志. 正在导出作业队列. 正在导出刷新组和子组在没有警告的情况下成功终止导出。
3.数据导入在NT服务器上通过ftp命令将导出的输出转存二进制文件expdat.dmp(使用binary传输模用Oracle for Digital Unix 数据导入工具命令行方式进行数据导入$imp gxmisdba/manager file=/expdat.dmp full=y log=u01import.logConnected to: Oracle8 Enterprise Edition Release 8.0.4.0.0 - ProductionPL/SQL Release 8.0.4.0.0 - ProductionExport file created by EXPORT:V08.00.05 via conventional path. importing GXMISDBAs objects into GXMISDBA. . importing table "AAAAA" 0 rows imported. . importing table "EVT_CARRIER_CONFIGURA TION" 0 rows imported. . importing table "TBL_AJ_STK" 331 rows importedIMP-00017: following statement failed with ORACLE error 2437:"ALTER TABLE "TBL_KJ_JLRY" ADD CONSTRAINT "PK_TBL_KJ_JLRY" PRIMARY KEY("FLD_KJ_JLRY_BH","FLD_KJ_JLRY_XM") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS255 STORAGE (INITIAL 10240 NEXT 10240 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 50 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)""ENABLE NOV ALIDATE"IMP-00003: ORACLE error 2437 encounteredORA-02437: cannot enable (GXMISDBA.PK_TBL_KJ_JLRY) - primary key violatedImport terminated successfully with warnings.数据导入出现20多个以上类似错误,后分析其中报错的"TBL_AJ_STK"表,发现"FLD_KJ_JLRY_XM"字段值(关键字组成之一)为中文字符而在Digital Unix服务器Oracle数据库中"FLD_KJ_JLRY_XM"字段值显示的为"????"(在客户端用Oracle Sql Plus查看),从而造成在客户端Oracle Sql Plus对某行显示"????"的字段值进行修改,如改成中文值”测试”,提交后,用SQL语句查看,刚修改的行中显示"????"的字段值变成了”测试”,这说明了Digital UNIN服务器上的Oracle数据集可以存储中文字符,但Oracle 8.0.4 for Digital UNIN的导入工具imp未能将Oracle 8.0.5 for Windows NT imp80导出的中文数据进行转换。
4.查看字符集参数4.1查看Oracle 8.0.5 for Windows NT props$内容NAME V ALUE$---------------------------------------DICT.BASE 2NLS_LANGUAGE AMERICANNLS_TERRITORY AMERICANLS_CURRENCY $NLS_ISO_CURRENCY AMERICANLS_NUMERIC_CHARACTERS.,NLS_CALENDAR GREGORIANNLS_DATE_FORMAT DD-MON-YYNLS_DATE_LANGUAGE AMERICANNLS_CHARACTERSET ZHS16GBKNLS_SORTBINARYNLS_NCHAR_CHARACTERSET ZHS16GBKNLS_RDBMS_VERSION8.0.5.0.0GLOBAL_DB_NAMEORACLE.WORLDEXPORT_VIEWS_VERSION7已选择15行。
4.2查看Oracle 8.0.4 for Digital UNIN 的props$内容SQL> connect sys/change_on_installNAME V ALUE$---------------------------------------DICT.BASE 2NLS_LANGUAGE AMERICANNLS_TERRITORY AMERICANLS_CURRENCY $NLS_ISO_CURRENCY AMERICANLS_NUMERIC_CHARACTERS .,NLS_CALENDAR GREGORIANNLS_DATE_FORMAT DD-MON-YYNLS_DATE_LANGUAGE AMERICANNLS_CHARACTERSET ZHS16CGB231280NLS_SORT BINARYNLS_NCHAR_CHARACTERSET ZHS16CGB231280NLS_RDBMS_VERSION 8.0.4.0.0GLOBAL_DB_NAME ORCL.WORLDEXPORT_VIEWS_VERSION715 rows selected.发现Oracle 8.0.4 for Digital UNIN 采用了Oracle在Digital Unix环境下建议的中文字符集ZHS16CGB231280,两者的字符集不同,于是本人就在Digital UNIN服务器上重新安装Oracle,选择了与NT上同样的字符集ZHS16GBK(中国简体汉字16位国标库)。
安装完成后,通过查看props$的内容,确认了Oracle 8.0.4 for Digital UNIN和Oracle 8.0.5 for Windows NT 的字符集一致。
于是用Oracle 8.0.4 for Digital UNIN的导入工具imp重新进行数据导入5.问题解决办法后来本人发现在Oracle 8.0.5 for Windows NT的服务器(或装有Oracle 8.0.5 for windows 95/98的工作站)上直接用Oracle 8.0.5 for Windows NT的导入工具imp80远程对Oracle 8.0.4 for Digital UNIN数据库进行数据导入,问题竟得到解决。
5.1在NT的服务器上,修改tnsnames.ora(或通过Oracle Net8 Easy config)设置数据库连接字符串gxmis(可自行设定)指向Oracle 8.0.4 for Digital UNIN服务器。
5.2在NT的服务器上进行数据远程导入c:>imp80 gxmisdba/manager@gxmis file=c:expdat.dmpfull=y log=c:import.log已连接到:Oracle8 Enterprise Edition Release 8.0.4.0.0 - ProductionPL/SQL Release 8.0.4.0.0 - Production经由常规路径导出由EXPORT:V08.00.05创建的文件. 正在将GXMISDBA的对象导入到GXMISDBA. . 正在导入表"AAAAA" 0行被导入. . 正在导入表"EVT_CARRIER_CONFIGURA TION" 0行被导入. . 正在导入表"TBL_AJ_AGKS" 331行被导入准备启用约束条件...成功终止导入5.3把Oracle 8.0.4 for Digital UNIN字符集重新又改成ZHS16CGB231280,进行数据远程导入测试,数据也同样地导入成功。