欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Oracle 常用SQL技巧收藏

程序员文章站 2022-05-29 21:28:59
...
[b]1. SELECT子句中避免使用 “*” [/b]

当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将“*” 依次转换成所有的列名, 这个工作是[u]通过查询数据字典[/u]完成的, 这意味着将耗费更多的时间.

[b]2.计算记录条数 [/b]

和一般的观点相反, count(*) 比count(1)稍快 ,当然如果可以通过索引检索,对索引列的计数仍旧是最快的. 例如 COUNT(EMPNO)

[b]3. 避免在索引列上使用计算 [/b]

WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用[u]全表扫描[/u]. 举例:

--低效:
SELECT …FROM DEPT WHERE SAL * 12 > 25000; 

--高效:
SELECT … FROM DEPT WHERE SAL  > 25000/12;  


[b]4. 用>=替代> [/b]

--如果DEPTNO上有一个索引

--高效:
 SELECT *  FROM EMP  WHERE DEPTNO >=4  

--低效:
SELECT *  FROM EMP   WHERE DEPTNO >3 

两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录.

[b]5.不用“<>”或者“!=”操作符[/b]

对不等于操作符的处理会造成全表扫描,可以用“<” or “>”代替。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。推荐方案:用其它相同功能的操作运算代替,如:
a<>0 改为 a>0 or a<0


[b]6.Where子句中出现IS NULL或者IS NOT NULL时,Oracle会停止使用索引而执行全表扫描。[/b]

可以考虑在设计表时,对索引列设置为NOT NULL。这样就可以用其他操作来取代判断NULL的操作,判断字段是否为空一般是不会应用索引的,因为B树索引是不索引空值的。推荐方案:不允许字段为空,而用一个缺省值代替空值,如业扩申请中状态字段不允许为空,缺省为“”。

[b]7.通配符不要位于查询字符串的第一个字符[/b]

LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。一个实际例子:用YW_YHJBQK表中营业编号后面的户标识号可来查询营业编号 YY_BH LIKE ‘%5400%’ 这个条件会产生全表扫描,如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 则会利用YY_BH的索引进行两个范围的查询,性能肯定大大提高。

[b]8.SQL书写的影响(共享SQL语句可以提高操作效率)[/b]

同一功能同一性能不同写法SQL的影响

如一个SQL在A程序员写的为
Select * from zl_yhjbqk

B程序员写的为
Select * from dlyx.zl_yhjbqk(带表所有者的前缀)

C程序员写的为
Select * from DLYX.ZLYHJBQK(大写表名)

D程序员写的为
Select * from DLYX.ZLYHJBQK(中间多了空格)

以上四个SQL在ORACLE分析整理之后产生的结果及执行的时间是一样的,但是从ORACLE共享内存SGA的原理,可以得出ORACLE对每个SQL 都会对其进行一次分析,并且占用共享内存,如果将SQL的字符串及格式写得完全相同则ORACLE只会分析一次,共享内存也只会留下一次的分析结果,这不仅可以减少分析SQL的时间,而且可以减少共享内存重复的信息,ORACLE也可以准确统计SQL的执行频率。

推荐方案:不同区域出现的相同的Sql语句,要保证查询字符完全相同,以利用SGA共享池,防止相同的Sql语句被多次分析。

[b]9.WHERE后面的条件顺序影响[/b]

Oracle从下到上处理Where子句中多个查询条件,所以表连接语句应写在其他Where条件前,可以过滤掉最大数量记录的条件必须写在Where子句的末尾。如:

Select * from zl_yhjbqk where dy_dj = '1KV以下' and xh_bz=1

Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1KV以下'

以上两个SQL中dy_dj(电压等级)及xh_bz(销户标志)两个字段都没进行索引,所以执行的时候都是全表扫描,第一条SQL的dy_dj = '1KV以下'条件在记录集内比率为99%,而xh_bz=1的比率只为0.5%,在进行第一条SQL的时候99%条记录都进行dy_dj及xh_bz的比较,而在进行第二条SQL的时候0.5%条记录都进行dy_dj及xh_bz的比较,以此可以得出第二条SQL的CPU占用率明显比第一条低。

[b]10.Order By语句中的非索引列会降低性能[/b]

可以通过添加索引的方式处理。严格控制在Order By语句中使用表达式

[b]11.使用表的别名[/b]

当在Sql语句中连接多个表时,使用表的别名,并将之作为每列的前缀。这样可以减少解析时间

[b]12.采用函数处理的字段不能利用索引[/b]

如:
substr(hbs_bh,1,4)=’5400’,优化处理:hbs_bh like ‘5400%’


[b]ORACLE在SQL执行分析方面已经比较成熟,如果分析执行的路径不对首先应在数据库结构(主要是索引)、服务器当前性能(共享内存、磁盘文件碎片)、数据库对象(表、索引)统计信息是否正确这几方面分析。[/b]