利用Oracle 10g SQL优化器(STA)优化语句
- 格式:docx
- 大小:48.89 KB
- 文档页数:21
Oracle 优化SQL 语句,提高效率我们都了解索引是相关表概念部分,主要是提高检索数据的相关效率,当Oracle 使用了较为复杂的自平衡 B-tree 结构时。
我们一般是通过索引查询数据 比全表扫描要快。
当 Oracle 找出执行查询和 Update 语句的最好路径时 , Oracle 优化将使用索引。
同样在联结多个表时使用索引也能够提高效率。
另一个使用索引的好处是 , 他提供了主键 (primary key ) 的唯一性验证。
那些 LON (或 LONCRAW 数据类型,您能够索引几乎任何的列。
通常,在大型表中使用 索引特别有效. 当然,您也会发现, 在扫描小表时,使用索引同样能提高效率。
虽然使用索引能得到查询效率的提高 , 但是我们也必须注意到他的代价。
索引需要空间来存储 ,也需要定期维护 , 每当有记录在表中增减或索引列被 修改时 , 索引本身也会被修改。
这意味着每条记录的 INSERT ,DELETE , UPDATE 将为此多付出 4、 5 次的磁盘 I/O 。
因为索引需要额外的存储空间和处理,那 些不必要的索引反而会使查询反应时间变慢。
定期的重构索引是有必要的:ALTER INDEX REBUILD1.用 EXISTS 替换 DISTINCT当提交一个包含一对多表信息 ( 比如部门表和雇员表 ) 的查询时,避免在SELECT?句中使用DISTINCT 。
一般能够考虑用 EXIST 替换,EXISTS 使查询更 为迅速,因为RDBM 核心模块将在子查询的条件一旦满足后, 立即返回结果。
例 子:(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHEREEXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO );2.SQL 语句用大写的;因为 Oracle 总是先解析SQL 语句,把小写的字母转 换成大写的再执行。
(Oracle管理)如何优化SQL语句以提高Oracle执行效率(1)选择最有效率的表名顺序(只在基于规则的优化器中有效):Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表drivingtable)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。
如果有3个以上的表连接查询,那就需要选择交叉表(intersectiontable)作为基础表,交叉表是指那个被其他表所引用的表。
(2)WHERE子句中的连接顺序:Oracle采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。
(3)SELECT子句中避免使用‘*’:Oracle在解析的过程中,会将‘*’依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。
(4)减少访问数据库的次数:Oracle在内部执行了许多工作:解析SQL语句,估算索引的利用率,绑定变量,读数据块等。
(5)在SQL*Plus,SQL*Forms和Pro*C中重新设置ARRAYSIZE参数,可以增加每次数据库访问的检索数据量,建议值为200。
(6)使用DECODE函数来减少处理时间:使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。
(7)整合简单,无关联的数据库访问:如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)。
(8)删除重复记录:最高效的删除重复记录方法(因为使用了ROWID)例子:DELETEFROMEMPEWHEREE.ROWID>(SELECTMIN(X.ROWID)FROMEMPXWHEREX.EMP_NO=E.EMP_NO);(9)用TRUNCATE替代DELETE:当删除表中的记录时,在通常情况下,回滚段(rollbacksegments)用来存放可以被恢复的信息.如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况)而当运用TRUNCATE时,回滚段不再存放任何可被恢复的信息。
10G中一些SQL优化的亮点1、优化器默认为CBO,OPTIMIZER_MODE默认值为ALL_ROWS。
不再使用古老的RBO模式,但RULE、CHOOSE并没有彻底消失,有些时候仍然可以作为我们调试的工具。
2、CPU Costing的计算方式现在默认为CPU+I/O两者之和.可通过DBMS_XPLAN.DISPLAY_CURSOR观察更为详细的执行计划。
3、增加了几个有用SQL Hints:INDEX_SS[[@block] tabs [inds]],INDEX_SS_ASC,INDEX_SS_DESC;SS为SKIP SCAN的缩写。
skip scan以前讨论的很多。
NO_USE_N[[@block]tabs],NO_USE_HAHS,NO_USE_MERGE,NO_INDEX_FFS,NO_INDEX_SS,NO_STAR_TRANS FORMATION,NO_QUERY_TRANSFORMATION.这几个HINT不用解释,一看就知道目的是什么。
USE_NL_WITH_INDEX([@block] tabs [index]):这个提示和Nested Loops 有关,通过提示我们可以指定Nested Loops循环中的内部表,也就是开始循环连接其他表的表。
CBO是否会执行取决于指定表是否有索引键关联。
QB_NAME(@blockname) 这个提示可以给某个查询定义一个name,并且可以在其他hints中使用这个name,并且将这个hints作用到这个name对应的查询中.其实从10G开始,Oracle对一些特定的查询自动使用queryblockname4、10G中支持在hint中使用queryblocknameselect*from a1 where id in (select/*+ qb_name(sub1) */ idfrom a1 where id in (2,10,12));Execution Plan----------------------------------------------------------Plan hash value: 173249654-----------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cos t (%CPU)| Time |-----------------------------------------------------------------------------------------|0|SELECT STATEMENT ||2|34|3 (34)|00:00:01||1|TABLE ACCESS BY INDEX ROWID| A1 |1|14|1 (0)|00:00:01||2| NESTED LOOPS ||2|34|3 (34)|00:00:01||3| SORT UNIQUE||2|6|1 (0)|00:00:01||4| INLIST ITERATOR |||||||*5|INDEX RANGE SCAN | IDX_A1_ID |2|6|1 (0)|00:00:01||*6|INDEX RANGE SCAN | IDX_A1_ID |1||0 (0)|00:00:01|--------------------------------------------------------------------------------------------------------select*from a1 where id in (select/*+ qb_name(sub1) full(@sub1 a1) */ idfrom a1 where id in (2,10,12));Plan hash value: 1882950619-----------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cos t (%CPU)| Time |-----------------------------------------------------------------------------------------|0|SELECT STATEMENT ||2|34|17 (6)|00:00:01||1|TABLE ACCESS BY INDEX ROWID| A1 |1|14|1 (0)|00:00:01||2| NESTED LOOPS ||2|34|17 (6)|00:00:01||3| SORT UNIQUE||2|6|15 (0)|00:00:01||*4|TABLE ACCESS FULL| A1 |2|6|15 (0)|00:00:01||*5|INDEX RANGE SCAN | IDX_A1_ID |1||0 (0)|00:00:01|----------------------------------------------------------------------------------------------------修改成错误的queryblocknameselect*from a1 where id in (select/*+ qb_name(sub1) full(@sub2 a1) */ id from a1 where id in (2,10,12));Execution Plan----------------------------------------------------------Plan hash value: 173249654-----------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cos t (%CPU)| Time |-----------------------------------------------------------------------------------------|0|SELECT STATEMENT ||2|34|3 (34)|00:00:01||1|TABLE ACCESS BY INDEX ROWID| A1 |1|14|1 (0)|00:00:01||2| NESTED LOOPS ||2|34|3 (34)|00:00:01||3| SORT UNIQUE||2|6|1 (0)|00:00:01||4| INLIST ITERATOR |||||||*5|INDEX RANGE SCAN | IDX_A1_ID |2|6|1 (0)|00:00:01||*6|INDEX RANGE SCAN | IDX_A1_ID |1||0 (0)|00:00:01|-----------------------------------------------------------------------------------------如果指定的queryblockname未定义,还是保持以前的执行计划,证明queryblockname起作用了.5、新的hints.spread_no_analysis、spread_min_analysis 用于优化analyze查询.具体以后测试下6、10GR2的一些变化.增强了AWR的报告, 提供了专门的ash报告,可以通过新的ashrpt.sql($ORACLE_HOME/rdbms/admin下)脚本产生我们需要的ash报告;提供了类似于statspack获取AWR库中某个sql(通过脚本)的统计信息和执行信息·streams_pool_size现在成为ASSM中的一员·自动调节DB_FILE_MULTIBLOCK_READ_COUNT参数,Oracle会根据数据库的访问自动调节该参数·增加了SQL的优化模式,提供了SQL Tuning Adsivor,SQL Profile等工具.可自动优化sql语句·两个比较重要的视图:v$PROCESS_MEMORY,动态监控每个进程的pga使用,v$sqlstats某种情况下可以替换v$sql视图。
S ql语句优化原则一、优化原则1、避免使用硬编码,改用绑定变量实现。
举例:String str =’ select * from t_zx_ryjbxxb where xm=’+params;上面这条语句使用了硬编码,使用这种方式存在两方面问题:每次执行sql语句时都需要重新解析sql语句;可能会遭遇sql注入攻击。
如在上面的语句中输入张三' or 1='1,则会把所有的记录都显示出来。
解决的方法就是使用占位符代替硬编码。
如下:String str =’select * from t_zx_ryjbxxb where xm=?’;2、当插入的数据为数据表中的记录数量的10%以上,首先需要删除该表的索引来提高数据的插入效率,当数据插入后,再建立索引。
3、避免在索引列上使用函数或计算,在where子句中,如果索引是函数的一部分,优化器将不再使用索引而使用全表扫描。
举例:低效:select * from dept where sal*12 >2500;高效:select * from dept where sal>2500/12;4、避免在索引列上使用not和“!=”,索引只能告诉什么存在于表中,而不能告诉什么不存在于表中,当数据库遇到not 和“!=”时,就会停止使用索引而去执行全表扫描。
5、使用关联查询替代in ,可以提高查询的效率。
6、使用not exists子查询替代not in。
在子查询中,NOT IN子句将执行一个内部的排序和合并。
无论在哪种情况下,NOT IN都是最低效的(因为它对子查询中的表执行了一个全表遍历)。
为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.举例:select * from t_zx_ryjbxxb where rybh not in(select rybh from t_zx_cqrb) and jwh=''select * from t_zx_ryjbxxb a where not exists(select1from t_zx_cqrb b where a.rybh =b.rybh)使用union-all 替代union:当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并,然后在输出最终结果前进行排序。
Oracle数据库的sql语句性能优化 在应⽤系统开发初期,由于开发数据库数据⽐较少,对于查询sql语句,复杂试图的编写等体会不出sql语句各种写法的性能优劣,但是如果将应⽤系统提交实际应⽤后,随着数据库中数据的增加,系统的响应速度就成为⽬前系统需要解决的最主要问题之⼀。
系统优化中⼀个很重要的⽅⾯就是sql语句的优化。
对于海量数据,劣质sql语句和优质sql语句之间的速度差别可以达到上百倍,可见对于⼀个系统不是简单地能实现其功能就⾏,⽽是要写出⾼质量的sql语句,提⾼系统的可⽤性。
Oracle的sql调优第⼀个复杂的主题,甚⾄需要长篇概论来介绍OracleSQL调优的细微差别。
不过有⼀些基本的规则是每个OracleDBA都需要遵从的,这些规则可以改善他们系统的性能。
sql调优的⽬标是简单的:消除不必要的⼤表全表搜索。
不必要的全表搜索导致⼤量不必要的磁盘I/O,从⽽拖慢整个数据库的性能,对于不必要的全表搜索来说,最常见的调优⽅法是增加索引,可以在表中加⼊标准的B树索引,也可以加⼊位图索引和基于函数的索引。
要决定是否消除⼀个全表搜索,你可以仔细检查索引搜索的I/O开销和全表搜索的开销,它们的开销和数据块的读取和可能的并⾏执⾏有关,并将两者作对⽐。
另外,在全表搜索是⼀个最快的访问⽅法时,将⼩表的全表搜索放到缓存(内存)中,也是⼀个⾮常明智的选择。
我们会发现现在诞⽣了很多基于内存的数据库管理系统,将整个数据库置于内存之中,性能将得到质的飞跃。
⼀、与索引相关的性能优化 在多数情况下,Oracle使⽤索引来更快地遍历表,优化器主要根据定义的索引来提⾼性能。
但是,如果在sql语句的where⼦句中写的sql代码不合理,就会造成优化器删去索引⽽使⽤全表扫描,⼀般这种sql语句就是所谓的劣质sql语句。
在编写sql语句时我们应清楚优化器根据何种原则来删除索引,这有助于写出⾼性能的sql语句。
1.IS NULL 与 IS NOT NULL 不能⽤null做索引,任何包含null值的列都将不会被包含在索引中,即使索引有多列这样的情况下,只要这些列中有⼀列含有null,该列就会从索引中排除。
Oracle sql 性能优化调整一、前言Oracle SQL是众多企业使用较多的关系型数据库之一,因其高效稳定的性能,以及其提供的强大功能,逐渐成为了广大企业进行信息系统开发、实施和数据管理的首选。
然而,在大数据时代,普通的SQL查询已经不能支撑企业的业务需求,尤其是在数据量庞大的情况下,SQL查询的效率和性能将会受到严重的制约。
本文旨在介绍Oracle SQL的性能优化调整方法,以提高企业的数据处理的效率和性能。
二、排查问题SQL性能优化的第一步是排查问题,需要对慢查询做出明确的定位。
首先需要对SQL进行分析,寻找哪个部分影响了SQL性能,包括:1.查询语句的风格是否规范。
2.SQL语句是否能够使用索引优化查询。
3.数据库的表大小是否合适。
4.缓存的大小是否合适。
5.应用响应时间是否过长。
在分析完成后,才能通过性能优化来解决问题。
三、优化处理1.优化SQL查询语句SQL查询最主要的性能瓶颈是IO瓶颈。
当表的大小超过1万条时,应该对查询语句进行合理的检索,即避免全表扫描。
对大于1万条的表,应该创建索引,以便提高SQL的效率。
2.优化SQL查询计划查询计划优化是SQL调优的关键。
因为优化查询计划是确定整个查询需要的资源和查询的优化路径。
优化查询计划意味着查询应该从哪些索引开始,除了哪些索引以外,以及使用哪些操作符等等。
这些优化计划将明显影响查询性能。
3.优化表结构和索引优化表结构和索引也是常用的Oracle SQL优化方法。
表结构的优化主要是考虑数据库表的设计是否符合0NF、1NF、3NF等规范,是否有多列重复,是否存在无用列,是否存在大型BLOB/CLOB列等问题。
对于索引优化,可以使用多个单列索引代替多列复合索引以提高查询更新效率。
此外,还可以考虑使用等值连接或外连接改变查询本身,以便减少查询的数据量。
4.优化服务器硬件和操作系统软件硬件和操作系统软件的优化也很重要,因为数据库运行的效率和性能取决于服务器硬件和操作系统软件是否能够同时支持PMI和CPU等高性能功能。
oracle数据库sql优化方案概述:在使用Oracle数据库进行开发和运维过程中,SQL语句的性能常常是一个关键问题。
本文将介绍一些基本的Oracle数据库SQL优化方案,旨在提高系统查询性能和响应速度。
1. SQL语句优化准则在进行SQL语句的优化之前,我们需要遵循以下准则:- 减少表之间的连接数量,尽量使用JOIN语句而不是子查询。
- 选择恰当的索引,合理利用索引可以提高查询效率。
- 避免使用SELECT *,仅选择需要的列。
- 尽量减少SQL语句中的函数使用,函数会增加查询的开销。
- 针对复杂查询,可以考虑使用分页查询或数据缓存等技术。
2. 查询计划分析查询计划是Oracle数据库优化的重要工具,通过分析查询计划可以找到潜在的性能问题。
可以使用以下工具进行查询计划分析:- 使用EXPLAIN PLAN命令生成查询计划。
- 使用SQL Trace功能记录SQL执行过程,通过跟踪文件进行分析。
- 使用Oracle Enterprise Manager等性能监控工具,查看查询计划和执行统计信息。
3. 索引优化索引是提高查询性能的重要手段,合理使用和优化索引可以显著提升系统的响应速度。
以下是一些索引优化的常用技巧:- 使用唯一索引替代非唯一索引,减少索引的冗余。
- 避免在过大的列上创建索引,可以使用函数索引或局部索引进行优化。
- 对经常用于查询的列创建索引,包括WHERE子句中经常使用的列和经常进行连接的列。
- 定期进行索引重建和统计信息收集。
4. 数据库配置优化除了对SQL语句进行优化,还可以通过调整数据库配置来提升性能:- 合理设置数据库的内存参数,包括共享池大小、缓冲池大小和PGA大小等。
- 设置适当的并发连接数,避免过度连接造成资源浪费。
- 配置硬盘存储方式,使用RAID技术提高数据存取速度。
- 使用数据库分区技术,将大表分成多个子表,提高查询效率。
5. 常见问题处理在优化SQL过程中,经常会遇到一些常见的性能问题,以下是一些处理方式:- 大数据量查询问题:可以考虑分页查询、增加合适的索引或引入缓存等手段来解决。
Oracle的SQL语句优化一、操作符优化1、IN 操作符用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。
但是用IN的SQL性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL 与不用IN的SQL有以下区别:ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。
由此可见用IN的SQL至少多了一个转换的过程。
一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。
推荐方案:在业务密集的SQL当中尽量不采用IN操作符,用EXISTS 方案代替。
2、NOT IN操作符此操作是强列不推荐使用的,因为它不能应用表的索引。
推荐方案:用NOT EXISTS 方案代替3、IS NULL 或IS NOT NULL操作(判断字段是否为空)判断字段是否为空一般是不会应用索引的,因为索引是不索引空值的。
推荐方案:用其它相同功能的操作运算代替,如:a is not null 改为a>0 或a>’’等。
不允许字段为空,而用一个缺省值代替空值,如申请中状态字段不允许为空,缺省为申请。
4、> 及< 操作符(大于或小于操作符)大于或小于操作符一般情况下是不用调整的,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化,如一个表有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的记录索引。
5、LIKE操作符LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。
千里之行,始于足下。
oracle数据库sql优化Oracle数据库是关系型数据库系统中的一种,在实际应用中,它的性能往往是关键因素之一。
为了提高Oracle数据库的性能,我们可以进行SQL优化。
SQL优化可以减少查询时间、减少资源消耗,提高数据库的整体性能。
首先,我们可以通过索引来优化SQL查询。
索引可以加快数据库的查找速度,减少查询的时间。
在选择索引时,我们可以根据查询的条件和数据的分布情况进行选择,合理选择索引可以大大提高查询效率。
另外,我们还可以考虑使用合适的查询语句。
比如,使用where子句来限制查询的范围,避免全表扫描;使用join来连接多个表,减少查询的次数;使用子查询来优化查询的复杂度等。
此外,在设计数据库时,我们也要考虑到数据的规范化和反规范化。
规范化有助于提高数据的一致性和可维护性,但在查询性能方面可能会受到一定的影响。
因此,对于经常被查询的数据,我们可以考虑进行反规范化,将其冗余存储在多个表中,以提高查询性能。
另外,我们还可以通过设置合适的数据库参数来优化SQL。
比如,通过调整SGA和PGA的大小来合理分配内存资源;通过调整数据库的缓冲池来提高缓存命中率;通过设置合适的日志模式来提高事务处理的效率等。
另外,一个高效的数据库应用还需要考虑到并发访问的问题。
通过合理的数据库设计和应用程序的编写,可以减少多个用户同时访问数据库时的冲突和阻塞,提高并发访问的效率。
第1页/共2页锲而不舍,金石可镂。
总之,通过合理的索引设计、合适的查询语句、数据库参数的优化和并发访问的处理,我们可以大大提高Oracle数据库的性能。
当然,在实际应用中,SQL优化是一个持续的过程,需要不断地进行监控和调整,以保持数据库的高性能。
SQL优化器(SQL Tuning Advisor STA)是Oracle10g中推出的帮助DBA优化工具,它的特点是简单、智能,DBA值需要调用函数就可以给出一个性能很差的语句的优化结果。
下面介绍一下它的使用。
使用STA一定要保证优化器是CBO模式下。
一、利用STA优化语句对于问题语句的收集,可以通过Oracle10g的另一个自动化工具:数据库自动诊断监视工具(ADDM)。
它的使用可以参照我的另一篇文章《Oracle10g数据库自动诊断监视工具(ADDM)使用指南》。
我们下面简单介绍一下如何优化一条找到的问题语句。
正如前面所述说的,STA是用起来很简单(只要你会调用存储过程,都能使用这个工具),三个步骤就可以完成一次语句调优。
测试环境创建:SQL> CREATE TABLE bigtab AS SELECT rownum as "id", a.* FROM dba_objects a;Table created.SQL> create table smalltab as select rownum as "id", a.* FROM dba_tables a;Table created.SQL> ALTER TABLE bigtab MODIFY (empno NUMBER);Table altered.SQL> DECLARE2 n NUMBER;3 BEGIN4 FOR n IN 1..1005 LOOP6 INSERT INTO bigtab SELECT rownum as "id", a.* FROM dba_objects a;7 COMMIT;8 END LOOP;9 END;/PL/SQL procedure successfully completed.这里创建一张大表和一张小表,并且都没有索引,下面执行一个查询:SQL> set timing onSQL> set autot onSQL> select count(*) from bigtab a, smalltab b where a.object_name=b.table_name;COUNT(*)----------135000Elapsed: 00:00:05.59Execution Plan----------------------------------------------------------Plan hash value: 3089226980--------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |--------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 36 | 3550 (2)| 00:00:43 || 1 | SORT AGGREGATE | | 1 | 36 | | ||* 2 | HASH JOIN | | 155K| 5462K| 3550 (2)| 00:00:43 || 3 | TABLE ACCESS FULL| SMALLTAB | 1223 | 22014 | 11 (0)| 00:00:01 | | 4 | TABLE ACCESS FULL| BIGTAB | 1205K| 20M| 3526 (1)| 00:00:43 | --------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")Statistics----------------------------------------------------------0 recursive calls0 db block gets16013 consistent gets14491 physical reads0 redo size412 bytes sent via SQL*Net to client385 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed可以看出这个语句执行性能很差:16013 consistent gets。
千里之行,始于足下。
oracle数据库sql优化
优化Oracle数据库SQL可以从多个方面考虑,以下是一些常见的SQL优化方法:
1. 使用索引:为查询中经常使用的列创建索引,可以加快查询速度。
2. 减少表之间的关联:尽量减少表之间的连接和关联操作,可以减少查询的复杂度和查询时间。
3. 使用EXPLAIN PLAN:使用EXPLAIN PLAN分析SQL语句的执行计划,找出执行计划中的性能瓶颈。
4. 使用合适的JOIN操作:根据具体的查询需求使用合适的JOIN操作,如INNER JOIN、LEFT JOIN等,避免使用不必要的JOIN操作。
5. 适当优化子查询:对于复杂的子查询,可以考虑将其结果存储在临时表中,并加上适当的索引。
6. 优化谓词:使用合适的谓词(如BETWEEN、IN、LIKE)进行查询,避免使用过于繁琐的谓词。
7. 避免使用通配符:%、_等通配符会导致全表扫描,应尽量避免使用。
8. 适当使用HINTS:可以通过使用HINTS来指定查询的优化路径,提高查询性能。
9. 拆分大的SQL语句:对于复杂的SQL语句,可以考虑将其拆分为多个较小的SQL语句,可以提高可读性和维护性。
10. 定期收集统计信息:通过定期收集统计信息,使Oracle数据库能够更好地选择合适的执行计划。
除了以上的方法,还可以根据具体的业务需求和查询情况进行一些特定的优化。
最终的目标是使查询尽可能快速和高效。
第1页/共1页。
Oracle优化SQL语句,提高效率我们都了解索引是相关表概念部分,主要是提高检索数据的相关效率,当Oracle使用了较为复杂的自平衡B-tree结构时。
我们一般是通过索引查询数据比全表扫描要快。
当 Oracle找出执行查询和Update语句的最好路径时, Oracle 优化将使用索引。
同样在联结多个表时使用索引也能够提高效率。
另一个使用索引的好处是,他提供了主键(primary key)的唯一性验证。
那些LONG或LONG RAW数据类型, 您能够索引几乎任何的列。
通常, 在大型表中使用索引特别有效. 当然,您也会发现, 在扫描小表时,使用索引同样能提高效率。
虽然使用索引能得到查询效率的提高,但是我们也必须注意到他的代价。
索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改。
这意味着每条记录的INSERT,DELETE , UPDATE 将为此多付出4、 5次的磁盘I/O 。
因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。
定期的重构索引是有必要的:ALTER INDEX REBUILD1.用EXISTS替换DISTINCT:当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT。
一般能够考虑用EXIST替换, EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立即返回结果。
例子:(低效): 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);2.SQL语句用大写的;因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。
优化sql语句提高oracle执行效率
1.尽可能高效:采用最有效的查询方式、避免使用不必要的查询语句、提高检索速度而非数据量。
2.避免使用子查询:尽量不使用子查询,把子查询换成联合查询或者
通过多表连接更新数据。
3.避免重复读取:尽量从数据库中读取一次数据,不要读取多次相同
的数据,避免多次查询,提高数据库的查询效率。
4.避免使用NOTIN和NOTEXISTS:尽量不用NOTIN和NOTEXISTS查询
语句,因为这种查询方式比较耗时,可以把NOTIN换成LEFTJOIN不为空
即可。
5.避免使用OR:尽量不用OR,用AND替代OR,AND通常比OR更有效。
6.避免使用模糊查询:尽量不用模糊查询,模糊查询效率较低,可以
用相似查询替代模糊查询。
7.合并多个表:如果有多个表,尽量合并这些表,以便减少查询次数。
8. 使用索引: 设置索引来提高查询速度,尽可能在 Where、Group by、Having、Order by等关键字中使用索引。
9. 优化sql语句顺序: 尽可能把WHERE条件的语句写在前面,以便
优先查询出少量的数据来,提高查询效率;把ORDER BY语句写在最后,
以便能有效地利用索引。
10.选择可用的查询方法:使用最适合的查询方法,选择适当的SELECT语句、JOIN语句和UNION语句,以使SQL语句更快地返回结果。
11. 避免使用Distinct: Distinct能会导致查询效率降低,尽量避免使用Distinct。
Oracle之SQL语句性能优化(34条优化⽅法)好多同学对sql的优化好像是知道的甚少,最近总结了以下34条仅供参考。
(1)选择最有效率的表名顺序(只在基于规则的优化器中有效):ORACLE的解析器按照从右到左的顺序处理FROM⼦句中的表名,FROM⼦句中写在最后的表(基础表 driving table)将被最先处理,在FROM⼦句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。
如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引⽤的表.(2) WHERE⼦句中的连接顺序.:ORACLE采⽤⾃下⽽上的顺序解析WHERE⼦句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最⼤数量记录的条件必须写在WHERE⼦句的末尾.(3)SELECT⼦句中避免使⽤ ‘ * ‘:ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个⼯作是通过查询数据字典完成的, 这意味着将耗费更多的时间(4)减少访问数据库的次数:ORACLE在内部执⾏了许多⼯作: 解析SQL语句, 估算索引的利⽤率, 绑定变量 , 读数据块等;(5)在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200(6)使⽤DECODE函数来减少处理时间:使⽤DECODE函数可以避免重复扫描相同记录或重复连接相同的表.(7)整合简单,⽆关联的数据库访问:如果你有⼏个简单的数据库查询语句,你可以把它们整合到⼀个查询中(即使它们之间没有关系)(8)删除重复记录:最⾼效的删除重复记录⽅法 ( 因为使⽤了ROWID)例⼦:DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)FROM EMP X WHERE X.EMP_NO = E.EMP_NO);(9)⽤TRUNCATE替代DELETE:当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) ⽤来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执⾏删除命令之前的状况) ⽽当运⽤TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运⾏后,数据不能被恢复.因此很少的资源被调⽤,执⾏时间也会很短. (译者按: TRUNCATE只在删除全表适⽤,TRUNCATE是DDL不是DML)(10)尽量多使⽤COMMIT:只要有可能,在程序中尽量多使⽤COMMIT, 这样程序的性能得到提⾼,需求也会因为COMMIT所释放的资源⽽减少:COMMIT所释放的资源:a. 回滚段上⽤于恢复数据的信息.b. 被程序语句获得的锁c. redo log buffer 中的空间d. ORACLE为管理上述3种资源中的内部花费(11)⽤Where⼦句替换HAVING⼦句:避免使⽤HAVING⼦句, HAVING 只会在检索出所有记录之后才对结果集进⾏过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE⼦句限制记录的数⽬,那就能减少这⽅⾯的开销. (⾮oracle中)on、where、having这三个都可以加条件的⼦句中,on是最先执⾏,where次之,having最后,因为on是先把不符合条件的记录过滤后才进⾏统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where也应该⽐having快点的,因为它过滤数据后才进⾏sum,在两个表联接时才⽤on的,所以在⼀个表的时候,就剩下where跟having⽐较了。
Oracle SQL优化方案1. 概述在Oracle数据库中,SQL语句是对数据库进行操作的重要手段。
然而,当数据量过大、表结构复杂或者SQL语句不够优化时,执行效率会受到影响,可能导致系统性能下降。
因此,设计和优化SQL语句是提升数据库性能的重要环节。
本文将介绍一些常见的Oracle SQL优化方案,包括索引优化、SQL语句重写、统计信息收集、SQL调优等,从而提高数据库的执行效率。
2. 索引优化索引是提高数据库查询效率的重要手段。
合理的索引设计可以极大地减少数据库的IO操作,加快查询速度。
以下是一些常见的索引优化方案:2.1 创建合适的索引根据实际业务需求和查询场景,创建合适的索引是提高查询效率的关键。
一般来说,对于经常用作查询条件的列,可以考虑创建索引。
然而,过多或者不必要的索引也会导致性能下降,因此需要综合考虑。
2.2 调整索引顺序对于复合索引,考虑到查询条件的顺序,将经常使用的条件列放在索引前面可以提高查询效率。
2.3 删除无用索引定期检查和删除无用的索引可以减少数据库存储空间占用,并提高数据库的更新操作效率。
3. SQL语句重写有时候,我们需要优化已有的SQL语句,通过改写或重构SQL语句来提高数据库的查询和操作效率。
以下是一些常见的SQL语句重写优化方案:3.1 使用连接(join)替代子查询在某些情况下,使用连接(join)可以替代子查询,减少数据库的查询次数,提高查询效率。
3.2 减少数据库的循环操作在SQL语句的编写过程中,需要注意尽量避免使用循环操作,尽量使用集合操作,从而减少数据库的查询次数,提高查询效率。
3.3 使用合适的SQL函数使用合适的SQL函数可以优化查询效率,如使用。
SQL优化器(SQL Tuning Advisor STA)是Oracle10g中推出的帮助DBA优化工具,它的特点是简单、智能,DBA值需要调用函数就可以给出一个性能很差的语句的优化结果。
下面介绍一下它的使用。
使用STA一定要保证优化器是CBO模式下。
一、利用STA优化语句对于问题语句的收集,可以通过Oracle10g的另一个自动化工具:数据库自动诊断监视工具(ADDM)。
它的使用可以参照我的另一篇文章《Oracle10g数据库自动诊断监视工具(ADDM)使用指南》。
我们下面简单介绍一下如何优化一条找到的问题语句。
正如前面所述说的,STA是用起来很简单(只要你会调用存储过程,都能使用这个工具),三个步骤就可以完成一次语句调优。
执行DBMS_SQLTUNE包进行sql优化需要有advisor的权限:SYS@ning>grant advisor to ning;Grant succeeded.使用DBMS_SQLTUNE包进行SQL优化,大致可以分为四个步骤:∙创建优化任务∙执行优化任务∙显示优化任务的结果∙按照建议执行优化测试环境创建:SQL> CREATE TABLE bigtab AS SELECT rownum as "id", a.* FROM dba_objects a;Table created.SQL> create table smalltab as select rownum as "id", a.* FROM dba_tables a;Table created.SQL> ALTER TABLE bigtab MODIFY (empno NUMBER); Table altered.SQL> DECLARE2 n NUMBER;3 BEGIN4 FOR n IN 1..1005 LOOP6 INSERT INTO bigtab SELECT rownum as "id", a.* FROM dba_objects a;7 COMMIT;8 END LOOP;9 END;/PL/SQL procedure successfully completed.这里创建一张大表和一张小表,并且都没有索引,下面执行一个查询:SQL> set timing onSQL> set autot onSQL> select count(*) from bigtab a, smalltab b where a.object_name=b.table_name;COUNT(*)----------135000Elapsed: 00:00:05.59Execution Plan----------------------------------------------------------Plan hash value: 3089226980--------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |--------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 36 | 3550 (2)| 00:00:43 || 1 | SORT AGGREGATE | | 1 | 36 | | ||* 2 | HASH JOIN | | 155K| 5462K| 3550 (2)| 00:00:43 || 3 | TABLE ACCESS FULL| SMALLTAB | 1223 | 22014 | 11 (0)| 00:00:01 || 4 | TABLE ACCESS FULL| BIGTAB | 1205K| 20M| 3526 (1)| 00:00:43 |--------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")Statistics----------------------------------------------------------0 recursive calls0 db block gets16013 consistent gets14491 physical reads0 redo size412 bytes sent via SQL*Net to client385 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed可以看出这个语句执行性能很差:16013 consistent gets。
第一步:创建优化任务并执行通过调用函数CREATE_TUNING_TASK来创建优化任务,调用存储过程EXECUTE_TUNING_TASK执行该任务:SQL> set autot offSQL> set timing offSQL> DECLARE2 my_task_name VARCHAR2(30);3 my_sqltext CLOB;4 BEGIN5 my_sqltext := 'select count(*) from bigtab a, smalltab b wherea.object_name=b.table_name';6 my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(7 sql_text => my_sqltext,8 user_name => 'DEMO',9 scope => 'COMPREHENSIVE',10 time_limit => 60,11 task_name => 'tuning_sql_test',12 description => 'Task to tune a query on a specified table');1314 DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'tuning_sql_test');15 END;16 /PL/SQL procedure successfully completed.在函数CREATE_TUNING_TASK,sql_text是需要优化的语句,user_name是该语句通过哪个用户执行,scope是优化范围(limited或comprehensive),time_limit优化过程的时间限制,task_name优化任务名称,description优化任务描述。
可以通过视图USER_ADVISOR_LOG和USER_ADVISOR_LOG来查看创建过的优化任务。
SQL> select task_name, status from USER_ADVISOR_LOG where task_name='tuning_sql_test';TASK_NAME STATUS------------------------------ -----------tuning_sql_test COMPLETED第二步:查看优化结果通过函数可以查看优化结果。
SQL> set long 10000SQL> set longchunksize 1000SQL> set linesize 100SQL> SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( 'tuning_sql_test') from DUAL;DBMS_SQLTUNE.REPORT_TUNING_TASK('TUNING_SQL_TEST')----------------------------------------------------------------------------------------------------GENERAL INFORMATION SECTION-------------------------------------------------------------------------------Tuning Task Name : tuning_sql_testTuning Task Owner : DEMOScope : COMPREHENSIVETime Limit(seconds) : 60Completion Status : COMPLETEDStarted at : 11/30/2005 13:16:43Completed at : 11/30/2005 13:16:44Number of Index Findings : 1Schema Name: DEMOSQL ID : 6p64dnnsqf9pmSQL Text : select count(*) from bigtab a, smalltab b wherea.object_name=b.table_name-------------------------------------------------------------------------------FINDINGS SECTION (1 finding)-------------------------------------------------------------------------------1- Index Finding (see explain plans section below)The execution plan of this statement can be improved by creating one or more indices.Recommendation (estimated benefit: 100%)----------------------------------------- Consider running the Access Advisor to improve the physical schema design or creating the recommended index.create index DEMO.IDX$$_06C50001 on DEMO.SMALLTAB('TABLE_NAME');- Consider running the Access Advisor to improve the physical schema design or creating the recommended index.create index DEMO.IDX$$_06C50002 on DEMO.BIGTAB('OBJECT_NAME');Rationale---------Creating the recommended indices significantly improves the execution plan of this statement. However, it might be preferable to run "Access Advisor"using a representative SQL workload as opposed to a single statement. This will allow to get comprehensive index recommendations which takes intoaccount index maintenance overhead and additional space consumption.EXPLAIN PLANS SECTION-------------------------------------------------------------------------------1- Original-----------Plan hash value: 3089226980--------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |--------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 36 | 3550 (2)| 00:00:43 || 1 | SORT AGGREGATE | | 1 | 36 | | ||* 2 | HASH JOIN | | 155K| 5462K| 3550 (2)| 00:00:43 || 3 | TABLE ACCESS FULL| SMALLTAB | 1223 | 22014 | 11 (0)| 00:00:01 || 4 | TABLE ACCESS FULL| BIGTAB | 1205K| 20M| 3526 (1)| 00:00:43 |--------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")2- Using New Indices--------------------Plan hash value: 494801882-----------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 36 | 1108 (3)| 00:00:14 || 1 | SORT AGGREGATE | | 1 | 36 | | ||* 2 | HASH JOIN | | 155K| 5462K| 1108 (3)| 00:00:14 || 3 | INDEX FAST FULL SCAN| IDX$$_06C50001 | 1223 | 22014 | 3 (0)| 00:00:01 || 4 | INDEX FAST FULL SCAN| IDX$$_06C50002 | 1205K| 20M| 1093 (2)| 00:00:14 | -----------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")-------------------------------------------------------------------------------看一下这个优化建议报告:第一部分是关于这次优化任务的基本信息:如任务名称、执行时间、范围、涉及到的语句等等。