ORACLE SQL语句优化技术要点解析

操作符优化:

IN 操作符

  用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。

  但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:

  ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。 由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。

  推荐方案:在业务密集的SQL当中尽量不采用IN操作符。

NOT IN操作符

  此操作是强列推荐不使用的,因为它不能应用表的索引。

  推荐方案:用NOT EXISTS 或(外连接+判断为空)方案代替

  <> 操作符(不等于)

  不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。

  推荐方案:用其它相同功能的操作运算代替,如

  a<>0 改为 a>0 or a<0
  a<>'' 改为 a>''

  IS NULL 或IS NOT NULL操作(判断字段是否为空)

  判断字段是否为空一般是不会应用索引的,因为B树索引是不索引空值的。

推荐方案:

  用其它相同功能的操作运算代替,如

  a is not null 改为 a>0 或a>''等。

  不允许字段为空,而用一个缺省值代替空值,如业扩申请中状态字段不允许为空,缺省为申请。

  建立位图索引(有分区的表不能建,位图索引比较难控制,如字段值太多索引会使性能下降,多人更新操作会增加数据块锁的现象)

  > 及 < 操作符(大于或小于操作符)

  大于或小于操作符一般情况下是不用调整的,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化,如一个表有100万记录,一个数值型字段 A,30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。那么执行A>2与A>=3的效果就有很大的区别了,因 为A>2时ORACLE会先找出为2的记录索引再进行比较,而A>=3时ORACLE则直接找到=3的记录索引。

LIKE操作符

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

UNION操作符

  UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION。如:

  select * from gc_dfys
  union
  select * from ls_jg_dfys

  这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。

  推荐方案:采用UNION ALL操作符替代UNION,因为UNION ALL操作只是简单的将两个结果合并后就返回。

  select * from gc_dfys
  union all
  select * from ls_jg_dfys

SQL书写的影响

  同一功能同一性能不同写法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的执行频率。

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占用率明显比第一条低。

查询表顺序的影响

  在FROM后面的表中的列表顺序会对SQL执行性能影响,在没有索引及ORACLE没有对表进行 统计分析的情况下ORACLE会按表出现的顺序进行链接,由此因为表的顺序不对会产生十分耗服务器资源的数据交叉。(注:如果对表进行了统计分 析,ORACLE会自动先进小表的链接,再进行大表的链接)

SQL语句索引的利用

对操作符的优化

  对条件字段的一些优化

  采用函数处理的字段不能利用索引,如:

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

  trunc(sk_rq)=trunc(sysdate),优化处理:

  sk_rq>=trunc(sysdate) and sk_rq

  进行了显式或隐式的运算的字段不能进行索引,如:

  ss_df+20>50,优化处理:ss_df>30

  ‘X'||hbs_bh>'X5400021452',优化处理:hbs_bh>'5400021542'

  sk_rq+5=sysdate,优化处理:sk_rq=sysdate-5

  hbs_bh=5401002554,优化处理:hbs_bh=' 5401002554',注:此条件对hbs_bh 进行隐式的to_number转换,因为hbs_bh字段是字符型。

  条件内包括了多个本表的字段运算时不能进行索引,如:

  ys_df>cx_df,无法进行优化

  qc_bh||kh_bh='5400250000',优化处理:qc_bh='5400' and kh_bh='250000'

  应用ORACLE的HINT(提示)处理

  提示处理是在ORACLE产生的SQL分析执行路径不满意的情况下要用到的。它可以对SQL进行以下方面的提示

  目标方面的提示:

  COST(按成本优化)

  RULE(按规则优化)

  CHOOSE(缺省)(ORACLE自动选择成本或规则进行优化)

  ALL_ROWS(所有的行尽快返回)

  FIRST_ROWS(第一行数据尽快返回)

  执行方法的提示:

  USE_NL(使用NESTED LOOPS方式联合)

  USE_MERGE(使用MERGE JOIN方式联合)

  USE_HASH(使用HASH JOIN方式联合)

  索引提示:

  INDEX(TABLE INDEX)(使用提示的表索引进行查询)

  其它高级提示(如并行处理等等)

总结

  ORACLE的提示功能是比较强的功能,也是比较复杂的应用,并且提示只是给ORACLE执行的 一个建议,有时如果出于成本方面的考虑ORACLE也可能不会按提示进行。根据实践应用,一般不建议开发人员应用ORACLE提示,因为各个数据库及服务 器性能情况不一样,很可能一个地方性能提升了,但另一个地方却下降了,ORACLE在SQL执行分析方面已经比较成熟,如果分析执行的路径不对首先应在数 据库结构(主要是索引)、服务器当前性能(共享内存、磁盘文件碎片)、数据库对象(表、索引)统计信息是否正确这几方面分析。

以上就是本文关于ORACLE SQL语句优化技术要点解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:oracle 数据库启动阶段分析 、 oracle 虚拟专用数据库详细介绍 、 浅谈oracle rac和分布式数据库的区别 、 Oracle RMAN自动备份控制文件方法介绍 等,有什么问题可以随时留言,小编必定及时回复大家,希望朋友们对我们多多支持!

(0)

相关推荐

  • Python使用cx_Oracle调用Oracle存储过程的方法示例

    本文实例讲述了Python使用cx_Oracle调用Oracle存储过程的方法.分享给大家供大家参考,具体如下: 这里主要测试在Python中通过cx_Oracle调用PL/SQL. 首先,在数据库端创建简单的存储过程. create or replace procedure test_msg(i_user in varchar2, o_msg out varchar2) is begin o_msg := i_user ||', Good Morning!'; end; 然后,开始在Pytho

  • 常用的Oracle doc命令(收藏)

    1.连接数据库 普通用户连接数据库: conn scott/tiger –(默认的用户名/密码).conn 即"connection"连接数据库的意思 超级管理员连接: Conn sys/sys as sysdba–oracle数据库不区分大小写 2.sql文件 保存sql文件 save c:\test.txt 编辑sql语句,用记事本编辑 ed c:\1.txt –编辑 SQL 语句 ed –直接打开上一次缓存sql语句 描述数据表的结构 desc employee; –打开empl

  • ORACLE批量导入图片到BLOB字段代码示例

    要插入图片的表不是固定的,而且是批量插入很多张,还要考虑到因为图片的文件名错误,修改后要再次插入,此时应避免已经插入的重复执行操作, 浪费时间. 所以就选择先用一张临时表来暂时保存从文件系统读取的照片,用DBMS_LOB的方法来处理. 第一步:创建一个数据库可以访问的目录(注意:这个目录是数据库服务器上的目录,不是客户机上的) -- Create directory create or replace directory 图片目录 as 'E:\照片'; 第二步:将图片文件放入刚建好的目录下面,

  • 浅谈oracle rac和分布式数据库的区别

    1.分布式数据库是多个数据库,而rac只是一个库多个实例: 2.rac事务上没有协调的问题,而分布式数据库由于是多个库需要事务上的协调: 3.分布式数据库数据是分散存储在各个节点,但是设备一般都是廉价的设备,经常出现节点故障,不过对用户来说是透明的:.RAC是ORACLE集群,数据是共享存储,只有一份,每个节点都不存放数据.节点可以宕,但是数据不会丢失: 4.分布式数据库支持的节点多,增加节点基本为线性增加:rac支持的节点数少,增加节点性能不是线性增加: 5.Oracle最大的问题在于shar

  • oracle数据匹配merge into的实例详解

    oracle数据匹配merge into的实例详解 前言: 很久之前,估计在2010年左右在使用Oralce,当时有个需求就是需要对两个表的数据进行匹配,这两个表的数据结构一致,一个是正式表,一个是临时表,这两表数据量还算是比较大几百M.业务需求是用临时表中的数据和正式表的匹配,所有字段都需要一一匹配,而且两表还没有主键,这是一个比较麻烦和糟糕的事情. 场景: 1.如果两表所有字段值都一致则不处理: 2.如果有部分字段不一致则更新: 3.如果正式表中数据在临时表中不存在,则需要删除: 满足上面场

  • Linux下修改Oracle监听地址的方法

    lisenter.ora 目录在 /opt/oracle/11g/network/admin LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.111.123)(PORT = 1521)) ) ) ADR_BASE_LISTENER = /opt/oracle tnsnames.o

  • oracle数据库导入导出命令解析

    Oracle数据导入导出imp/exp 功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢失). Oracle有个好处,虽然你的电脑不是服务器,但是你装了oracle客户端,并建立了连接(通过Net Configuration Assistant添加正确的服务命名,其实你可以想成是客户端与服务器端 修了条路,然后数据就可以被拉过来了) 这样你可以把数据导出到本地,虽然可能服务器离你很远.

  • ORACLE SQL语句优化技术要点解析

    操作符优化: IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格. 但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别: ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询. 由此可见用IN的SQL至少多了一个转换的过程.一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了. 推荐方案:

  • Oracle数据库性能优化技术开发者网络Oracle

    正在看的ORACLE教程是:Oracle数据库性能优化技术开发者网络Oracle.介绍:细处着手,巧处用功.高手和菜鸟之间的差别就是:高手什么都知道,菜鸟知道一些.电脑小技巧收集最新奇招高招,让你轻松踏上高手之路.  摘要: Oracle数据库是当前应用最广泛的大型数据库之一,而其性优化直接关系到系统的运行效率.本文以数据库性能优化的基本原则为出发点,阐述了在数据库设计阶段如何避免竞争和如何优化数据访问,在数据库运行阶段如何从操作系统和数据库实例级别上调整内存和I/O来达到数据库性能优化的各种技

  • Oracle SQL性能优化系列学习二

    正在看的ORACLE教程是:Oracle SQL性能优化系列学习二.  4. 选择最有效率的表名顺序(只在基于规则的优化器中有效) ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(

  • Oracle SQL性能优化系列学习一

    正在看的ORACLE教程是:Oracle SQL性能优化系列学习一.1. 选用适合的ORACLE优化器 ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性) 设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖. 为了使用基于成本的优化器(CBO,

  • 数据库SQL语句优化总结(收藏)

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉好的话推荐给更多的人,让更多的人看到.纠正以及补充. 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id f

  • 常用SQL语句优化技巧总结【经典】

    本文实例总结了常用SQL语句优化技巧.分享给大家供大家参考,具体如下: 除了建立索引之外,保持良好的SQL语句编写习惯将会降低SQL性能问题发生. ①通过变量的方式来设置参数 好: stringsql = "select * from people p where p.id = ? "; 坏: stringsql = "select * from people p where p.id = "+id; 数据库的SQL文解析和执行计划会保存在缓存中,但是SQL文只要有

  • Oracle SQL性能优化系列学习三

    正在看的ORACLE教程是:Oracle SQL性能优化系列学习三.8. 使用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 'SM

  • sql语句优化的一般步骤详解

    前言 本文主要给大家分享了关于sql语句优化的一般步骤,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.通过 show status 命令了解各种 sql 的执行频率 mysql 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信息,也可以在操作系统上使用 mysqladmin extend-status 命令获取这些消息. show status 命令中间可以加入选项 session(默认) 或 global: se

  • SQL语句优化之JOIN和LEFT JOIN 和 RIGHT JOIN语句的优化

    在数据库的应用中,我们经常需要对数据库进行多表查询,然而当数据量非常大时多表查询会对执行效率产生非常大的影响,因此我们在使用JOIN和LEFT JOIN 和 RIGHT JOIN语句时要特别注意: SQL语句的join原理: 数据库中的join操作,实际上是对一个表和另一个表的关联,而很多错误理解为,先把这两个表来一个迪卡尔积,然后扔到内存,用where和having条件来慢慢筛选,其实数据库没那么笨的,那样会占用大量的内存,而且效率不高,比如,我们只需要的一个表的一些行和另一个表的一些行,如果

  • 30种SQL语句优化的方法汇总

    1)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2)应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 3)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null  可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from

随机推荐