㈠ Oracle查询速度优化问题
1. 选用适合的ORACLE优化器
ORACLE的优化器共有3种:
a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性)
设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在sql句级或是会话(session)级对其进行覆盖.
为了使用基于成本的优化器(CBO, Cost-Based Optimizer) , 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性.
如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关. 如果table已经被analyze过, 优化器模式将自动成为CBO , 反之,数据库将采用RULE形式的优化器.
在缺省情况下,ORACLE采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器.
2. 访问Table的方式
ORACLE 采用两种访问表中记录的方式:
a. 全表扫描
全表扫描就是顺序地访问表中每条记录. ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描.
b. 通过ROWID访问表
你可以采用基于ROWID的访问方式情况,提高访问表的效率, , ROWID包含了表中记录的物理位置信息..ORACLE采用索引(INDEX)实现了数据和存放数据的物理位置(ROWID)之间的联系. 通常索引提供了快速访问ROWID的方法,因此那些基于索引列的查询就可以得到性能上的提高.
3. 共享SQL语句
为了不重复解析相同的SQL语句,在第一次解析之后, ORACLE将SQL语句存放在内存中.这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享. 因此,当你执行一个SQL语句(有时被称为一个游标)时,如果它
和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的
执行路径. ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用.
可惜的是ORACLE只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适用于多表连接查询.
数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了.
当你向ORACLE 提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句.
这里需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须完全相同(包括空格,换行等).
4.选择最有效率的表名顺序(只在基于规则的优化器中有效)
ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.
5. WHERE子句中的连接顺序.
ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.
6. SELECT子句中避免使用 ‘ * ‘
当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*' 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.
7. 减少访问数据库的次数
当执行每条SQL语句时, ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等. 由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作量.
注意: 在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200.
8. 使用DECODE函数来减少处理时间
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.
9. 整合简单,无关联的数据库访问
如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)
10. 删除重复记录
最高效的删除重复记录方法 ( 因为使用了ROWID)
DELETE FROM EMP E
WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X
WHERE X.EMP_NO = E.EMP_NO);
11. 用EXISTS替代IN
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率.
12. 用NOT EXISTS替代NOT IN
在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS
㈡ 如何实现oracle 数据库集群的优化
1、1、调整数据结构的设计。这一部分在开发信息系统之前完成,程序员需要考虑是否使用ORACLE数据库的分区功能,对于经常访问的数据库表是否需要建立索引等。
2、2、调整应用程序结构设计。这一部分也是在开发信息系统之前完成,程序员在这一步需要考虑应用程序使用什么样的体系结构,是使用传统的Client/Server两层体系结构,还是使用Browser/Web/Database的三层体系结构。不同的应用程序体系结构要求的数据库资源是不同的。
3、3、调整数据库SQL语句。应用程序的执行最终将归结为数据库中的SQL语句执行,因此SQL语句的执行效率最终决定了ORACLE数据库的性能。ORACLE公司推荐使用ORACLE语句优化器(Oracle Optimizer)和行锁管理器(row-level manager)来调整优化SQL语句。
4、4、调整服务器内存分配。内存分配是在信息系统运行过程中优化配置的,数据库管理员可以根据数据库运行状况调整数据库系统全局区(SGA区)的数据缓冲区、日志缓冲区和共享池的大小;还可以调整程序全局区(PGA区)的大小。需要注意的是,SGA区不是越大越好,SGA区过大会占用操作系统使用的内存而引起虚拟内存的页面交换,这样反而会降低系统。
5、5、调整硬盘I/O,这一步是在信息系统开发之前完成的。数据库管理员可以将组成同一个表空间的数据文件放在不同的硬盘上,做到硬盘之间I/O负载均衡。
6、6、调整操作系统参数,例如:运行在UNIX操作系统上的ORACLE数据库,可以调整UNIX数据缓冲池的大小,每个进程所能使用的内存大小等参数。
实际上,上述数据库优化措施之间是相互联系的。ORACLE数据库性能恶化表现基本上都是用户响应时间比较长,需要用户长时间的等待。但性能恶化的原因却是多种多样的,有时是多个因素共同造成了性能恶化的结果,这就需要数据库管理员有比较全面的计算机知识,能够敏感地察觉到影响数据库性能的主要原因所在。另外,良好的数据库管理工具对于优化数据库性能也是很重要的。
㈢ sql优化器基于规则优化器和基于成本优化器的区别
Oracle有两种优化器:RBO和CBO。 RBO的最大的问题在于它是靠硬编码在ORACLE数据库代码中的一系列规定的规则来决定目标SQL的执行计划的,而并没有考虑目标SQL中所涉及的对象的时间数据量,实际数据分布情况,这样一旦规定规则并不适用于该SQL中所涉及的实际对象时,RBO根据规定规则产生的执行计划就很可能不是当前情况下的最优执行计划了。
下面我们来看如下的例子:
select * from EMP_TEMP where manager_id=100;
假设在EMP_TEMP的manager_id上事先有名为IDX_MGR_TEMP的单键值B数索引,如果我们用的是RBO,则不管EMP_TEMP的数据量多大,也不管MANAGER_ID的数据分布如何,ORACLE执行的时候始终会选择做对IDX_MGR_TEMP的范围索引扫描,并回表取得EMP_TEMP中的记录。ORACLE是不会选择全表扫描EMP_TEMP表的,因为对于RBO而言,全表扫描的等级值要高于索引范围扫描值的等级值。
RBO的这种选择在表EMP_TEMP的数据量不大,而且满足manager_id=10的条件的记录少的情况下是影响不大的,如果表EMP_TEMP的数据量非常大,例如1000万条记录,
而且这1000万条记录的MANAGER_ID的值都是100,在这种极端的情况下,如果是RBO,显然它任然用IDX_MGR_TEMP索引范围扫描,这个时候性能肯定是很差的。因为相当于以单块顺序扫描所有的1000万行索引,然后再回表1000万次。显然没有使用多块以全表扫描方式直接扫描表EMP_TEMP的执行效率高。所以为了解决RBO的这个先天的缺陷,从ORACLE 7开始,ORACLE就引入了CBO。CBO在选择目标SQL的执行计划时,是用执行成本作为判断原则的。CBO会从目标SQL诸多可能的执行路径中选择一条成本值最小的执行路径作为其执行计划,各条执行路径的成本是根据目标SQL语句所涉及的表,索引,列等相关对象的统计信息计算出来的。这些信息存储在ORACLE的数据库的数据字典里,且从多个维度描述了ORACLE数据库里相关对象的实际数据量,实际数据分布等详细信息。
NOTE:ORACLE在对一条执行路径计算成本时,并不一定从头到尾完整计算完,只是要ORACLE在计算过程中发现算出来的部分成本值已经大于之前保存下来的到目前为止的最小成本值,就会马上终止对当前执行路径成本值的计算,并转而开始计算下一条新的执行路径的成本。这个过程会一直持续下去,直到目标SQL的给各个可能的执行路径全部计算完毕或已经达到预先定义好的待计算的执行路径数量的阀值。
RBO是根据硬编码在ORACLE数据库中来决定目标SQL的执行计划的,并没有考虑目标SQL所所涉及的对象的实际数据量,实际分布情况等。而CBO则恰恰相反,它会根据目标SQL的相关的对象的实际数据量,实际数据分布情况的统计信息来决定其执行计划,即意味着CBO是随着目标SQL中所涉及的对象的统计信息的变化而变化的。这就意味着只有统计信息相对准确,则用CBO来解析目标SQL会比同等条件下的RBO来解析得到正确执行计划的概率要高。
当然CBO并不是完美的,它的缺陷主要表现在:
1,CBO会默认目标SQL语句的WHERE条件中出现的各个列之间是独立的,没有关系的。
2,CBO会假设所有的目标SQL都是单独执行的,并且互不干扰。
3,CBO对直方图统计信息有诸多限制。
4,CBO在解析多个表关联的目标SQL时,可能会漏掉正确的执行计划。
㈣ 如何进行oracle数据库性能优化
你最好买一本专门讲ORACLE性能优化的书,好好看看\x0d\x0a1、调整数据库服务器的性能\x0d\x0aOracle数据库服务器是整个系统的核心,它的性能高低直接影响整个系统的性能,为了调整Oracle数据库服务器的性能,主要从以下几个方面考虑: \x0d\x0a1.1、调整操作系统以适合Oracle数据库服务器运行\x0d\x0aOracle数据库服务器很大程度上依赖于运行服务器的操作系统,如果操作系统不能提供最好性能,那么无论如何调整,Oracle数据库服务器也无法发挥其应有的性能。 \x0d\x0a1.1.1、为Oracle数据库服务器规划系统资源 \x0d\x0a据已有计算机可用资源, 规划分配给Oracle服务器资源原则是:尽可能使Oracle服务器使用资源最大化,特别在Client/Server中尽量让服务器上所有资源都来运行Oracle服务。 \x0d\x0a1.1.2、调整计算机系统中的内存配置 \x0d\x0a多数操作系统都用虚存来模拟计算机上更大的内存,它实际上是硬盘上的一定的磁盘空间。当实际的内存空间不能满足应用软件的要求时,操作系统就将用这部分的磁盘空间对内存中的信息进行页面替换,这将引起大量的磁盘I/O操作,使整个服务器的性能下降。为了避免过多地使用虚存,应加大计算机的内存。 \x0d\x0a1.1.3、为Oracle数据库服务器设置操作系统进程优先级 \x0d\x0a不要在操作系统中调整Oracle进程的优先级,因为在Oracle数据库系统中,所有的后台和前台数据库服务器进程执行的是同等重要的工作,需要同等的优先级。所以在安装时,让所有的数据库服务器进程都使用缺省的优先级运行。 \x0d\x0a1.2、调整内存分配\x0d\x0aOracle数据库服务器保留3个基本的内存高速缓存,分别对应3种不同类型的数据:库高速缓存,字典高速缓存和缓冲区高速缓存。库高速缓存和字典高速缓存一起构成共享池,共享池再加上缓冲区高速缓存便构成了系统全程区(SGA)。SGA是对数据库数据进行快速访问的一个系统全程区,若SGA本身需要频繁地进行释放、分配,则不能达到快速访问数据的目的,因此应把SGA放在主存中,不要放在虚拟内存中。内存的调整主要是指调整组成SGA的内存结构的大小来提高系统性能,由于Oracle数据库服务器的内存结构需求与应用密切相关,所以内存结构的调整应在磁盘I/O调整之前进行。 \x0d\x0a1.2.1、库缓冲区的调整 \x0d\x0a库缓冲区中包含私用和共享SQL和PL/SQL区,通过比较库缓冲区的命中率决定它的大小。要调整库缓冲区,必须首先了解该库缓冲区的活动情况,库缓冲区的活动统计信息保留在动态性能表v$librarycache数据字典中,可通过查询该表来了解其活动情况,以决定如何调整。 \x0d\x0a \x0d\x0aSelect sum(pins),sum(reloads) from v$librarycache; \x0d\x0a \x0d\x0aPins列给出SQL语句,PL/SQL块及被访问对象定义的总次数;Reloads列给出SQL 和PL/SQL块的隐式分析或对象定义重装载时在库程序缓冲区中发生的错误。如果sum(pins)/sum(reloads) ≈0,则库缓冲区的命中率合适;若sum(pins)/sum(reloads)>1, 则需调整初始化参数 shared_pool_size来重新调整分配给共享池的内存量。 \x0d\x0a1.2.2、数据字典缓冲区的调整 \x0d\x0a数据字典缓冲区包含了有关数据库的结构、用户、实体信息。数据字典的命中率,对系统性能影响极大。数据字典缓冲区的使用情况记录在动态性能表v$librarycache中,可通过查询该表来了解其活动情况,以决定如何调整。 \x0d\x0a \x0d\x0aSelect sum(gets),sum(getmisses) from v$rowcache; \x0d\x0a \x0d\x0aGets列是对相应项请求次数的统计;Getmisses 列是引起缓冲区出错的数据的请求次数。对于频繁访问的数据字典缓冲区,sum(getmisses)/sum(gets)<10%~15%。若大于此百分数,则应考虑增加数据字典缓冲区的容量,即需调整初始化参数shared_pool_size来重新调整分配给共享池的内存量。 \x0d\x0a1.2.3、缓冲区高速缓存的调整 \x0d\x0a用户进程所存取的所有数据都是经过缓冲区高速缓存来存取,所以该部分的命中率,对性能至关重要。缓冲区高速缓存的使用情况记录在动态性能表v$sysstat中,可通过查询该表来了解其活动情况,以决定如何调整。 \x0d\x0a \x0d\x0aSelect name,value from v$sysstat where name in ('dbblock gets','consistent gets','physical reads'); \x0d\x0a \x0d\x0adbblock gets和consistent gets的值是请求数据缓冲区中读的总次数。physical reads的值是请求数据时引起从盘中读文件的次数。从缓冲区高速缓存中读的可能性的高低称为缓冲区的命中率,计算公式: \x0d\x0a \x0d\x0aHit Ratio=1-(physical reds/(dbblock gets+consistent gets)) \x0d\x0a \x0d\x0a如果Hit Ratio<60%~70%,则应增大db_block_buffers的参数值。db_block_buffers可以调整分配给缓冲区高速缓存的内存量,即db_block_buffers可设置分配缓冲区高速缓存的数据块的个数。缓冲区高速缓存的总字节数=db_block_buffers的值*db_block_size的值。db_block_size 的值表示数据块大小的字节数,可查询 v$parameter 表: \x0d\x0a \x0d\x0aselect name,value from v$parameter where name='db_block_size'; \x0d\x0a \x0d\x0a在修改了上述数据库的初始化参数以后,必须先关闭数据库,在重新启动数据库后才能使新的设置起作用。
㈤ oralce sql优化。
看下这个查询sql是比你的查询快还是慢
SELECT S_ECIF_IP_AND_AST_RLTNP.NEXTVAL,
C.CONT_ID,
A.HOLDING_ID,
2,
'',
'',
SYSDATE
FROM TEMP_HOUSE_CONTEQUIV A
INNER JOIN ECIFSGA.FCC_PRPCINSURED B ON A.PROPOSALNO = B.PROPOSALNO
INNER JOIN CONTEQUIV C ON B.INSUREDCODE = C.ADMIN_CLIENT_ID
AND C.ADMIN_SYS_TP_CD <> 100000
inner join CONTACT H on C.CONT_ID = H.CONT_ID
where INACTIVATED_DT IS NULL
AND SUBSTR(B.INSUREDFLAG, 0, 1) = 1
㈥ oracle plsql 如何优化sql
加索引,加分区,走索引,走分区
㈦ 在oracle数据库中,影响优化器生成执行计划的因素有哪些
9i前的RBO不熟,也就不敢妄言。
关于10g后的CBO,谈下我的理解。
首先,影响优化器执行计划最主要的因素是统计信息。优化器根据统计信息情况,单表上选择全表扫描还是索引。表联接方式上选择嵌套,哈希还是合并排序。不同的统计信息将会生成不同的执行计划。很多时候发现之前跑的好好的sql,突然变慢了,多数情况下重新收集下统计信息便解决了。统计信息这一块需要关注直方图这一块,很多生产环境都存在数据倾斜的情况,如若未准确收集直方图,那么生成的执行计划便有失偏颇。
--------------------------------------------------------------------------------------------------------------------
第二点,sql语句的写法问题。比如字段上有索引,但谓词条件写成like '%xxx%'方式,将导致该字段上索引不可用。比如表连接方式用<>之类,将无法使用hash join。其实这些与其说是写法问题,倒不如说是oracle自身有一定的编码规则,符合该规则条件,方可用到index之类。
--------------------------------------------------------------------------------------------------------------------
第三点,也是最无奈的一点,CBO的自身缺陷问题。很多时候,统计信息是最新的,也符合写法规范,但CBO就是不生成我们所期待的执行计划。这个时候,通常要改变sql语句的逻辑写法,比如标量子查询可否换成左连接,用with as替换一些子查询等,以期待oracle生成更高效率的执行计划。另外,就是使用hint来迫使CBO生成你所期待的执行计划,但CBO不一定就范。
谈及缺陷,也不算不上缺陷,尤其是表越多,将会出现更多排列的可能性,oracle不可能将所有执行计划都生成出来然后选择一个最优的,定是按照一定比例择取,但具体多少,我不详。也就是说,DBA完全可以凭借自身对你所管理的oracle了解程度,给sql语句指定一个最优的执行计划。
--------------------------------------------------------------------------------------------------------------------
其他还有一些细节问题,可在日常工作中慢慢体会,cbo还是相当强大的。
㈧ 执行一下Oracle SQL时,慢如蜗牛,如何优化
这样给出的SQL没有人可以帮助你优化,如果你真的希望有人可以帮助你,你需要将这个SQL的执行计划和你的优化器模式贴出来,这样才可以给你一点建议,
㈨ Oracle数据库该如何着手优化一个SQL
SQL Profile是10g中的新特性,作为自动SQL调整过程的一部分。SQL Profile是一个对象,它包含了可以帮助查询优化器为一个特定的SQL语句找到高效执行计划的信息。这些信息包括执行环境、对象统计和对查询优化器所做评估的修正信息。
它的最大优点之一就是在不修改SQL语句和会话执行环境的情况下影响查询优化器的决定。SQL Profile中包含的并非单个执行计划的信息,SQL Profile不会固定一个SQL语句的执行计划。当表的数据增长或者索引创建、删除,使用同一个SQL Profile的执行计划可能会改变,而存储在SQL Profile中的信息会继续起作用。所以,经过一段很长的时间之后,它的信息有可能会过时,需要重新生成。