Oracle SQL语句优化
ORACLE常用SQL优化hint语句
ORACLE常用SQL优化hint语句在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法:1. /*+ALL_ROWS*/表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.例如:SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’;2. /*+FIRST_ROWS*/表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.例如:SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’;3. /*+CHOOSE*/表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;例如:SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’;4. /*+RULE*/表明对语句块选择基于规则的优化方法.例如:SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’;5. /*+FULL(TABLE)*/表明对表选择全局扫描的方法.例如:SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO=’SCOTT’;6. /*+ROWID(TABLE)*/提示明确表明对指定表根据ROWID进行访问.例如:SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>=’AAAAAAAAAAAAAA’AND EMP_NO=’SCOTT’;7. /*+CLUSTER(TABLE)*/提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.例如:SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMSWHERE DPT_NO=’TEC304′ AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;8. /*+INDEX(TABLE INDEX_NAME)*/表明对表选择索引的扫描方法.例如:SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX=’M';9. /*+INDEX_ASC(TABLE INDEX_NAME)*/表明对表选择索引升序的扫描方法.例如:SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO=’SCOTT’;10. /*+INDEX_COMBINE*/为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式.例如:SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMSWHERE SAL<5000000 AND HIREDATE11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/提示明确命令优化器使用索引作为访问路径.例如:SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE FROM BSEMPMS WHERE SAL<60000;12. /*+INDEX_DESC(TABLE INDEX_NAME)*/表明对表选择索引降序的扫描方法.例如:SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';13. /*+INDEX_FFS(TABLE INDEX_NAME)*/对指定的表执行快速全索引扫描,而不是全表扫描的办法.例如:SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/提示明确进行执行规划的选择,将几个单列索引的扫描合起来.例如:SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO='TDC306';15. /*+USE_CONCAT*/对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询.例如:SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';16. /*+NO_EXPAND*/对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展.例如:SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';17. /*+NOWRITE*/禁止对查询块的查询重写操作.18. /*+REWRITE*/可以将视图作为参数.19. /*+MERGE(TABLE)*/能够对视图的各个查询进行相应的合并.例如:SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NOAND A.SAL>V.AVG_SAL;20. /*+NO_MERGE(TABLE)*/对于有可合并的视图不再合并.例如:SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;21. /*+ORDERED*/根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接.例如:SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;22. /*+USE_NL(TABLE)*/将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.例如:SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;23. /*+USE_MERGE(TABLE)*/将指定的表与其他行源通过合并排序连接方式连接起来.例如:SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;24. /*+USE_HASH(TABLE)*/将指定的表与其他行源通过哈希连接方式连接起来.例如:SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;25. /*+DRIVING_SITE(TABLE)*/强制与ORACLE所选择的位置不同的表进行查询执行.例如:SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;26. /*+LEADING(TABLE)*/将指定的表作为连接次序中的首表.27. /*+CACHE(TABLE)*/当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端例如:SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;28. /*+NOCACHE(TABLE)*/当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端例如:SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;29. /*+APPEND*/直接插入到表的最后,可以提高速度.insert /*+append*/ into test1 select * from test4 ;30. /*+NOAPPEND*/通过在插入语句生存期内停止并行模式来启动常规插入.insert /*+noappend*/ into test1 select * from test4 ;---------------------------------------------------------------------------- Optimization Approaches Access MethodsALL_ROWS AND_EQUALCHOOSE CLUSTERFIRST RULES FULLRULE HASHParallel Execution HASH_AJAPPEND*ORDERED HASH_SJ ***STAR**INDEXSTAR_TRANSFORMATION*INDEX_ASCJoin Operations INDEX_COMBINE*DRIVING_SITE*INDEX_DESCUSE_HASH**INDEX_FFS*USE_MERGE MERGE_AJ**USE_NL MERGE_SJ***Additional Hints ROW_IDCACHE USE_CONCATNOCACHE NO_EXPAND***PUSH_SUBQ REWRITE***MERGE***NOREWRITE***NO_MERGE*Join OrdersPUSH_JOIN_PRED***NO_PUSH_JOIN_PRED***NOAPPEND*ORDERED PREDICATES***NOPARALLELPARALLELPARALLEL_INDEX*NO_PARALLEL_INDEX***----------------------------------------------------------------------------并且使用基本的试探法生成执行计划。
Oracle优化SQL语句,提高效率
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语句优化技术分析1
3、带通配符(%)的like语句
这个 sql 在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集, 如果表数据量大的话可能会导致用磁盘进行排序。
推荐方案:采用 union all 操作符替代 union,因为 union all 操作只是简单的将两个结果合并后就 返回。
select * from gc_dfys union all select * from ls_jg_dfys
一、问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询 SQL 语句,复杂视图的的编写等体会不出 SQL 语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应 速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是 SQL 语句的优化。 对于海量数据,劣质 SQL 语句和优质 SQL 语句之间的速度差别可以达到上百倍,可见对于一个系统不是简 单地能实现其功能就可,而是要写出高质量的 SQL 语句,提高系统的可用性。
第一种格式是使用IN操作符: ... where column in(select * from ... where ...);
第二种格式是使用EXIST操作符: ... where exists (select 'X' from ...where ...);
ORACLE数据库SQL语句优化讲稿
ORACLESQL语句优化SQL Select语句完整的执行顺序1、from子句组装来自不同数据源的数据;2、where子句基于指定的条件对记录行进行筛选;3> group by子句将数据划分为多个分组;4、使用聚集函数进行计算;5、使用having 了-句筛选分组;6、计算所有的表达式;7、使用order by对结果集进行排序。
说明:—8) SELECT (9) DISTINCT (11) <T0P_spec辻ication> <select_list>—(1) FROM <left_table>—(3) <join_type> JOIN <right_table>—(2) ON <join_condition>—(4) WHERE <where_condit ion>—(5) GROUP BY <group_by_list>—(6) WITH {CUBE ROLLUP}—(7) HAVING <having_condition>~(10) ORDER BY <order_by_list>Oracle SQL性能优化技巧1、选用适合的ORACLE优化器2、访问Table的方式3、共享SQL语句4、选择最有效率的表名顺序(只在基于规则的优化器中有效)5、 WHERE子句中的连接顺序6、SELECT子句中避免使用'* '7、减少访问数据库的次数8、使用DECODE函数来减少处理时间9、整合简单,无关联的数据库访问10、删除重复记录11、用 TRUNCATE 替代 DELETE12、尽量多使用COMMIT13、计算记录条数14、用Where子句替换HAVING子句13、减少对表的查询16、通过内部函数提高SQL效率17、使用表的别名(Alias)18、用 EXISTS 替代 IN19、用 NOT EXISTS 替代 \0T IN20、用表连接替换EXISTS21、用 EXISTS 替换 DISTINCT1.选用适合的ORACLE优化器ORACLE的优化器共有3种a、 RULE (基于规则)b、 COST (基于成本)c、 CHOOSE (选择性)设置缺省的优化器,可以通过对init. ora文件中OPTIMIZER.MODE参数的各种声明,如 RULE, COST, CHOOSE, ALL_ROWS, FIRST_ROWS。
oracle sql 优化技巧
oracle sql 优化技巧(实用版3篇)目录(篇1)1.Oracle SQL 简介2.优化技巧2.1 减少访问数据库次数2.2 选择最有效率的表名顺序2.3 避免使用 SELECT2.4 利用 DECODE 函数2.5 设置 ARRAYSIZE 参数2.6 使用 TRUNCATE 替代 DELETE2.7 多使用 COMMIT 命令2.8 合理使用索引正文(篇1)Oracle SQL 是一款广泛应用于各类大、中、小微机环境的高效、可靠的关系数据库管理系统。
为了提高 Oracle SQL 的性能,本文将为您介绍一些优化技巧。
首先,减少访问数据库的次数是最基本的优化方法。
Oracle 在内部执行了许多工作,如解析 SQL 语句、估算索引的利用率、读数据块等,这些都会大量耗费 Oracle 数据库的运行。
因此,尽量减少访问数据库的次数,可以有效提高系统性能。
其次,选择最有效率的表名顺序也可以明显提升 Oracle 的性能。
Oracle 解析器是按照从右到左的顺序处理 FROM 子句中的表名,因此,合理安排表名顺序,可以减少解析时间,提高查询效率。
在执行 SELECT 子句时,应尽量避免使用,因为 Oracle 在解析的过程中,会将依次转换成列名,这是通过查询数据字典完成的,耗费时间较长。
DECODE 函数也是一个很好的优化工具,它可以避免重复扫描相同记录,或者重复连接相同的表,提高查询效率。
在 SQLPlus 和 SQLForms 以及 ProC 中,可以重新设置 ARRAYSIZE 参数。
该参数可以明显增加每次数据库访问时的检索数据量,从而提高系统性能。
建议将该参数设置为 200。
当需要删除数据时,尽量使用 TRUNCATE 语句替代 DELETE 语句。
执行 TRUNCATE 命令时,回滚段不会存放任何可被恢复的信息,所有数据不能被恢复。
因此,TRUNCATE 命令执行时间短,且资源消耗少。
在使用 Oracle 时,尽量多使用 COMMIT 命令。
oracle性能优化,SQL语句全优化,SQL语句执行效率问题
oracle性能优化,SQL语句全优化,SQL语句执行效率问题oracle性能优化文档共50条选择其中4条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语句必须完全相同(包括空格,换行等). 共享的语句必须满足三个条件:A. 字符级的比较: 当前被执行的语句和共享池中的语句必须完全相同. 例如:SELECT * FROM EMP;和下列每一个都不同SELECT * from EMP;Select * From Emp;SELECT * FROM EMP;B. 两个语句所指的对象必须完全相同: 例如:用户对象名如何访问Jack sal_limit private synonymWork_city public synonymPlant_detail public synonymJill sal_limit private synonymWork_city public synonymPlant_detail table owner考虑一下下列SQL语句能否在这两个用户之间共享.SQL 能否共享原因select max(sal_cap) from sal_limit 不能每个用户都有一个private synonym - sal_limit, 它们是不同的对象select count(*) from work_city where sdesc like 'NEW%' 能两个用户访问相同的对象public synonym - work_cityselect a.sdesc,b.location from work_city a , plant_detail b where a.city_id = b.city_id 不能用户jack 通过private synonym访问plant_detail 而jill 是表的所有者,对象不同C. 两个SQL语句中必须使用相同的名字的绑定变量(bind variables) 例如:第一组的两个SQL语句是相同的(可以共享),而第二组中的两个语句是不同的(即使在运行时,赋于不同的绑定变量相同的值)select pin , name from people where pin = :blk1.pin;select pin , name from people where pin = :blk1.pin;select pin , name from people where pin = :blk1.ot_ind;select pin , name from people where pin = :blk1.ov_ind;4. 选择基础表Oracle的SQL语句执行效率问题查找与解决方法一、识别占用资源较多的语句的方法(4种方法)1. 测试组和最终用户反馈的与反应缓慢有关的问题。
oracle 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语句优化
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语句优化规则整理目录1.选用适合的ORACLE优化器 --------------------------------------------------------------------- 32.访问Table的方式ORACLE 采用两种访问表中记录的方式---------------------------- 33. 共享SQL语句 ---------------------------------------------------------------------------------------- 34. 选择最有效率的表名顺序(只在基于规则的优化器中有效) --------------------------- 55.WHERE子句中的连接顺序。
-------------------------------------------------------------------- 66.SELECT子句中避免使用‘ * ’------------------------------------------------------------- 67.减少访问数据库的次数-------------------------------------------------------------------------- 78.使用DECODE函数来减少处理时间------------------------------------------------------------ 89.整合简单,无关联的数据库访问 ------------------------------------------------------------- 810.删除重复记录 -------------------------------------------------------------------------------------- 911.用TRUNCATE替代DELETE ----------------------------------------------------------------------- 912.尽量多使用COMMIT ------------------------------------------------------------------------------- 913.计算记录条数 ------------------------------------------------------------------------------------- 1014.用Where子句替换HAVING子句-------------------------------------------------------------- 1015.减少对表的查询 ---------------------------------------------------------------------------------- 1116.通过内部函数提高SQL效率。
oracle数据库sql优化
千里之行,始于足下。
oracle数据库sql优化Oracle数据库是关系型数据库系统中的一种,在实际应用中,它的性能往往是关键因素之一。
为了提高Oracle数据库的性能,我们可以进行SQL优化。
SQL优化可以减少查询时间、减少资源消耗,提高数据库的整体性能。
首先,我们可以通过索引来优化SQL查询。
索引可以加快数据库的查找速度,减少查询的时间。
在选择索引时,我们可以根据查询的条件和数据的分布情况进行选择,合理选择索引可以大大提高查询效率。
另外,我们还可以考虑使用合适的查询语句。
比如,使用where子句来限制查询的范围,避免全表扫描;使用join来连接多个表,减少查询的次数;使用子查询来优化查询的复杂度等。
此外,在设计数据库时,我们也要考虑到数据的规范化和反规范化。
规范化有助于提高数据的一致性和可维护性,但在查询性能方面可能会受到一定的影响。
因此,对于经常被查询的数据,我们可以考虑进行反规范化,将其冗余存储在多个表中,以提高查询性能。
另外,我们还可以通过设置合适的数据库参数来优化SQL。
比如,通过调整SGA和PGA的大小来合理分配内存资源;通过调整数据库的缓冲池来提高缓存命中率;通过设置合适的日志模式来提高事务处理的效率等。
另外,一个高效的数据库应用还需要考虑到并发访问的问题。
通过合理的数据库设计和应用程序的编写,可以减少多个用户同时访问数据库时的冲突和阻塞,提高并发访问的效率。
第1页/共2页锲而不舍,金石可镂。
总之,通过合理的索引设计、合适的查询语句、数据库参数的优化和并发访问的处理,我们可以大大提高Oracle数据库的性能。
当然,在实际应用中,SQL优化是一个持续的过程,需要不断地进行监控和调整,以保持数据库的高性能。
优化sql语句提高oracle执行效率
优化sql语句提高oracle执行效率
• (8)用TRUNCATE替代DELETE: • 当删除表中的记录时,在通常情况下, 回滚段 (rollback segments ) 用来存放可以被恢复 的信息. 如果你没有COMMIT事 务,ORACLE会将数据恢复到删除之前的状 态(准确地说是恢复到执行删除命令之前的 状况) 而当运用TRUNCATE时, 回滚段不再 存放任何可被恢复的信息。当命令运行后, 数据不能被恢复.因此很少的资源被调用,执 行时间也会很短。(TRUNCATE只在删除 全表适用,TRUNCATE是DDL不是DML)。
优化sql语句提高oracle执行效率
• (2)WHERE子句中的连接顺序: • Oracle采用自下而上的顺序解析WHERE子 句,根据这个原理,表之间的连接必须写在其 他WHERE条件之前, 那些可以过滤掉最大 数量记录的条件必须写在WHERE子句的末 尾。 • (3)SELECT子句中避免使用‘*’:
优化sql语句提高oracle执行效率
• where次之,having最后,因为on是先把不 符合条件的记录过滤后才进行统计,它就 可以减少中间运算要处理的数据,按理说 应该速度是最快的,where也应该比having 快点的,因为它过滤数据后才进行sum,在 两个表联接时才用on的,所以在一个表的 时候,就剩下
优化sql语句提高oracle执行效率
• ROUND((BUFFER_GETSDISK_READS)/BUFFER_GETS,2) Hit_radio, • ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run, • SQL_TEXT • FROM V$SQLAREA • WHERE EXECUTIONS>0 • AND BUFFER_GETS > 0 • AND (BUFFER_GETSDISK_READS)/BUFFER_GETS < 0.8 • ORDER BY 4 DESC;
oracle sql优化常用的15种方法
oracle sql优化常用的15种方法1. 使用合适的索引索引是提高查询性能的重要手段。
在设计表结构时,根据查询需求和数据特点合理地添加索引。
可以通过创建单列索引、复合索引或者位图索引等方式来优化SQL查询。
2. 确保SQL语句逻辑正确SQL语句的逻辑错误可能会导致低效查询。
因此,在编写SQL语句前,需要仔细分析查询条件,确保逻辑正确性。
3. 使用连接替代子查询在一些场景下,使用连接(JOIN)操作可以替代子查询,从而减少查询的复杂度。
连接操作能够将多个数据集合合并为一个结果集,避免多次查询和表的扫描操作。
4. 避免使用通配符查询通配符查询(如LIKE '%value%')在一些情况下可能导致全表扫描,性能低下。
尽量使用前缀匹配(LIKE 'value%')或者使用全文索引进行模糊查询。
5. 注意选择合适的数据类型选择合适的数据类型有助于提高SQL查询的效率。
对于整型数据,尽量使用小范围的数据类型,如TINYINT、SMALLINT等。
对于字符串数据,使用CHAR字段而不是VARCHAR,可以避免存储长度不一致带来的性能问题。
6. 优化查询计划查询计划是数据库在执行SQL查询时生成的执行计划。
通过使用EXPLAIN PLAN命令或者查询计划工具,可以分析查询计划,找出性能瓶颈所在,并对其进行优化。
7. 减少磁盘IO磁盘IO是影响查询性能的重要因素之一。
可以通过增加内存缓存区(如SGA)、使用高速磁盘(如SSD)、使用合适的文件系统(如ASM)等方式来减少磁盘IO。
8. 分区表对于大数据量的表,可以考虑使用分区表进行查询优化。
分区表可以将数据按照某个规则分散到不同的存储区域,从而减少查询范围和加速查询。
9. 批量操作尽量使用批量操作而不是逐条操作,可以减少数据库的事务处理开销,提高SQL执行效率。
可以使用INSERT INTO SELECT、UPDATE、DELETE等批量操作语句来实现。
Oracle优化SQL语句,提高效率
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语句,把小写的字母转换成大写的再执行。
ORACLESQL性能优化
ORACLESQL性能优化1.使用正确的查询语句:使用正确的查询语句是提高SQL性能的关键。
确定要返回的结果集,只选择所需的列,使用合适的过滤条件和连接条件来减少需要检索的数据量。
2.创建适当的索引:索引是提高查询性能的重要因素之一、为经常使用的列创建索引可以加快查询速度。
但是,过多或不必要的索引可能会降低性能。
因此,只为那些经常用于查询和过滤的列创建索引。
3. 根据数据分布选择合适的索引类型:Oracle提供了多种类型的索引,包括B-tree索引、位图索引和哈希索引。
根据数据分布选择合适的索引类型可以提高查询性能。
4. 使用合适的查询优化技术:Oracle提供了多种查询优化技术,如联接、子查询、视图和分区等。
选择合适的查询优化技术可以提高查询性能。
5. 避免重复查询:在同一查询中避免多次访问相同的表和数据。
可以使用临时表或Oracle的WITH子句来保存查询结果,以便以后多次使用。
6.使用绑定变量:绑定变量可以减少SQL执行时间并减少资源的消耗。
使用绑定变量可以将SQL缓存起来以供以后使用,避免重复解析查询。
7.使用合适的数据库连接方式:选择合适的数据库连接方式可以提高查询性能。
使用连接池可以避免频繁的连接和断开操作,减少资源消耗。
8. 监控和调优SQL语句:使用Oracle提供的监控工具来监控和调优SQL语句的执行。
根据监控结果进行优化,从而提高SQL查询性能。
9.确保数据库统计信息的及时更新:数据库统计信息对于优化查询非常重要。
及时更新统计信息可以帮助优化器选择合适的执行计划,提高查询性能。
10.使用合适的硬件和存储配置:选择合适的硬件和存储配置可以提高查询性能。
增加内存和磁盘的速度和容量可以减少IO开销,加快查询速度。
总结起来,Oracle SQL性能优化需要综合考虑查询语句、索引、查询优化技术、数据库连接方式、绑定变量、监控和调优等因素。
通过合理地应用这些技术和方法,可以显著提高SQL查询的执行速度和效率。
ORACLE常用SQL优化hint语句
ORACLE常⽤SQL优化hint语句在SQL语句优化过程中,我们经常会⽤到hint,现总结⼀下在SQL优化过程中常见Oracle HINT的⽤法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化⽅法,并获得最佳吞吐量,使资源消耗最⼩化. 例如: SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’; 2. /*+FIRST_ROWS*/ 表明对语句块选择基于开销的优化⽅法,并获得最佳响应时间,使资源消耗最⼩化. 例如: SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’; 3. /*+CHOOSE*/ 表明如果数据字典中有访问表的统计信息,将基于开销的优化⽅法,并获得最佳的吞吐量; 表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化⽅法; 例如: SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’; 4. /*+RULE*/ 表明对语句块选择基于规则的优化⽅法. 例如: SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’; 5. /*+FULL(TABLE)*/ 表明对表选择全局扫描的⽅法. 例如: SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO=’SCOTT’; 6. /*+ROWID(TABLE)*/ 提⽰明确表明对指定表根据ROWID进⾏访问. 例如: SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>=’AAAAAAAAAAAAAA’ AND EMP_NO=’SCOTT’; 7. /*+CLUSTER(TABLE)*/ 提⽰明确表明对指定表选择簇扫描的访问⽅法,它只对簇对象有效. 例如: SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS WHERE DPT_NO=’TEC304′ AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO; 8. /*+INDEX(TABLE INDEX_NAME)*/ 表明对表选择索引的扫描⽅法. 例如: SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX=’M'; 9. /*+INDEX_ASC(TABLE INDEX_NAME)*/ 表明对表选择索引升序的扫描⽅法. 例如: SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO=’SCOTT’; 10. /*+INDEX_COMBINE*/ 为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合⽅式. 例如: SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS WHERE SAL<5000000 AND HIREDATE 11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/ 提⽰明确命令优化器使⽤索引作为访问路径. 例如: SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE FROM BSEMPMS WHERE SAL<60000; 12. /*+INDEX_DESC(TABLE INDEX_NAME)*/ 表明对表选择索引降序的扫描⽅法. 例如: SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT'; 13. /*+INDEX_FFS(TABLE INDEX_NAME)*/ 对指定的表执⾏快速全索引扫描,⽽不是全表扫描的办法. 例如: SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305'; 14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/ 提⽰明确进⾏执⾏规划的选择,将⼏个单列索引的扫描合起来. 例如: SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO='TDC306'; 15. /*+USE_CONCAT*/ 对查询中的WHERE后⾯的OR条件进⾏转换为UNION ALL的组合查询. 例如: SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M'; 16. /*+NO_EXPAND*/ 对于WHERE后⾯的OR 或者IN-LIST的查询语句,NO_EXPAND将阻⽌其基于优化器对其进⾏扩展. 例如: SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M'; 17. /*+NOWRITE*/ 禁⽌对查询块的查询重写操作. 18. /*+REWRITE*/ 可以将视图作为参数. 能够对视图的各个查询进⾏相应的合并. 例如: SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO ,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL; 20. /*+NO_MERGE(TABLE)*/ 对于有可合并的视图不再合并. 例如: SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL; 21. /*+ORDERED*/ 根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接. 例如: SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 ANDB.COL1=C.COL1; 22. /*+USE_NL(TABLE)*/ 将指定表与嵌套的连接的⾏源进⾏连接,并把指定表作为内部表. 例如: SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO; 23. /*+USE_MERGE(TABLE)*/ 将指定的表与其他⾏源通过合并排序连接⽅式连接起来. 例如: SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHEREBSEMPMS.DPT_NO=BSDPTMS.DPT_NO; 24. /*+USE_HASH(TABLE)*/ 将指定的表与其他⾏源通过哈希连接⽅式连接起来. 例如: SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHEREBSEMPMS.DPT_NO=BSDPTMS.DPT_NO; 25. /*+DRIVING_SITE(TABLE)*/ 强制与ORACLE所选择的位置不同的表进⾏查询执⾏. 例如: SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO; 26. /*+LEADING(TABLE)*/ 将指定的表作为连接次序中的⾸表. 27. /*+CACHE(TABLE)*/ 当进⾏全表扫描时,CACHE提⽰能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使⽤端 例如: SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS; 当进⾏全表扫描时,CACHE提⽰能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使⽤端 例如: SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS; 29. /*+APPEND*/ 直接插⼊到表的最后,可以提⾼速度. insert /*+append*/ into test1 select * from test4 ; 30. /*+NOAPPEND*/ 通过在插⼊语句⽣存期内停⽌并⾏模式来启动常规插⼊. insert /*+noappend*/ into test1 select * from test4 ;----------------------------------------------------------------------------Optimization Approaches Access MethodsALL_ROWS AND_EQUALCHOOSE CLUSTERFIRST RULES FULLRULE HASHParallel Execution HASH_AJAPPEND*ORDERED HASH_SJ ***STAR**INDEXSTAR_TRANSFORMATION*INDEX_ASCJoin Operations INDEX_COMBINE*DRIVING_SITE*INDEX_DESCUSE_HASH**INDEX_FFS*USE_MERGE MERGE_AJ**USE_NL MERGE_SJ***Additional Hints ROW_IDCACHE USE_CONCATNOCACHE NO_EXPAND***PUSH_SUBQ REWRITE***MERGE***NOREWRITE***NO_MERGE*Join OrdersPUSH_JOIN_PRED***NO_PUSH_JOIN_PRED***NOAPPEND*ORDERED PREDICATES***NOPARALLELPARALLELPARALLEL_INDEX*NO_PARALLEL_INDEX*** 提⽰(hint)从Oracle7中引⼊,⽬的是弥补基于成本优化器的缺陷。
Oracle之SQL语句性能优化(34条优化方法)
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语句优化
数据库的操作 。 所 以本文 从O r a c l e 数 据库 执行S Q L 语句 的过程 入手, 逐步研 究优化s Q L 语句的方法。
数据库应用程序 的执行最终将归结为数 据库中的S Q L 语句 执行。 S Q L 语句消耗了数 据库的大部分资源。因此S Q L 语句 的执
1 S QL 优化 的必要 性与 目的
个组件 的优化 , 包括应用程 序优化 、 实例 和数据库 优化和环境 的就是将性 能低下的S Q L 语句 转换性能优异 的S Q L 语句, 使数据
优化 。 对应用程序 的优化通常可分为两个方面 : 源代码的优化和 查找的路径最佳化 , 并尽量保持C P U 时间 ̄ i i / o 时间的平衡。 在
Q L 语句优化的实质就是用优化器可 以识别 的的调整组件 以改善 S
性能, 即增加吞吐量和减少响应 时间。 从整体上看调优是对各 引来 减少表扫描的I / 0 次 数, 尽量避 免表 搜索的发 生。 优化的 目
行效率最终 决定O R A C L E 数据库 的性能 , 也就决定的应 用系统 的
数 据库系统 是管 理信息系 统 的核心 , 查 询操 作在各 类数 性能。 下面通过实例 介绍s Q L 语句优化 的若干方法。 据库操作 中占据比重最大 , 查询速度 直接 影响数据库的应 用效 2 . 1建立有效的索引 率, 对 于大 型数据库来说, 显得更为重要 , 由于查询操作在S Q L
优 化 成为 系统性 能提 高的主要 途 径 。 本 文针对 0 r a c l e 数据 库 的S Q L 调整 和优 化 , 论述 ̄ ' S Q L 优化的目 的和原 则 , 并通 过若 干 实例 , 介 绍 了S Q L
语 句优化 的一些方法。
oracle优化-SQL优化
Oracle优化—SQL优化1、数据库、数据表、数据表数据库、数据表、数据表I/O优化原则数据库规划原则●最大可重用化⏹数据库重大问题时,通过备份和恢复机制最大程度上恢复数据●最小磁盘争用⏹数据库文件平均分布在不同的磁盘上,避免多用户访问时争用同一磁盘●各种数据的合理分布⏹将数据库中的各种数据按特性(如基表和变化表、大数据和常规数据)存储在不同的文件中。
●数据表规划原则⏹数据定义精确化◆满足要求的情况下,选择占用资源最少的数据类型以提高DBMS的I/O性能⏹表的抽象化◆通过将具有共性的表合并,将其特性以标识字段表示⏹表的范式化◆设计表时,满足1NF(原子性)、2NF(键相关性)、3NF(无函数相关性),保证表的结构无冗余●数据表I/O优化原则⏹变化表和基表的分离◆将变化表(递增性很强,如单据表、销售记录表)和基表(很少变化,如学生资源、班组资料等)分开存放到不同的数据文件中⏹大数据和常规数据的分离◆将表的long、lob等大数据字段和其他常规类型字段分开存放,保证常规数据的查询高效性⏹索引数据和表数据的分离◆将索引和表分离,减少磁盘争用;并提高索引的查询效率2、选用适合的ORACLE优化器优化器RBO/CBOOracle的优化器有两种优化方式,即基于规则的优化方式(Rule-Based Optimization,简称为RBO)和基于代价的优化方式(Cost-Based Optimization,简称为CBO),在Oracle8及以后的版本,Oracle强列推荐用CBO的方式。
RBO方式:优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则。
比如我们常见的,当一个where子句中的一列有索引时去走索引。
CBO方式:它是看语句的代价(Cost),这里的代价主要指Cpu和内存。
优化器在判断是否用这种方式时,主要参照的是表及索引的统计信息。
统计信息给出表的大小、有少行、每行的长度等信息。
这些统计信息起初在库内是没有的,是做analyze命令后才出现的,很多的时侯过期统计信息会令优化器做出一个错误的执行计划,因些应及时更新这些信息。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
I.概念
A.选择性和基数
1.选择性:选择性(selectivity)介于0和1之间。
代表选中记录占总数的百分
比。
例如,如果一个操作需要从一张表读取120条记录,在应用一个过滤条
件后返回了其中18条记录,选择性就是0.15(18/120)
2.基数:一个操作返回的记录条数称为基数(cardinality)
3.两者关系:cardinality=selectivity*num_rows
4.查询基数计算:
a.不包含聚合操作
查询语句返回记录数
b.包含聚合函数例如group by
聚合函数:对数据进行汇总处理的函数,如max,min,avg等
根据汇总前的选择条件计算基数。
B.逻辑读和物理读
1.逻辑读:当服务器进程访问到高速缓存(buffer cache)中的一个数据块的时候
就执行了一次逻辑读。
2.物理读:当服务器进程需要访问高速缓存不存在的数据块时产生一次物理读。
需要打开数据文件,读取这个数据块,并且将数据块存放到高速缓存中。
II.执行计划
A.获取执行计划的方法
1.执行SQL语句explain plan,然后查询结果输出表
explain plan for select * from scott.emp where deptno=10 order by ename;
select * from table(dbms_xplan.display);
2.sqlplus或pl/sql developer中的set autotrace traceonly;
可以给出执行计划和逻辑读的统计信息。
在PL/SQL DEVELOPER里按F5
select * from scott.emp where deptno=10 order by ename;
3.查询自动工作量资料库(Automatic Workload Repository)或statspack报表
B.解释执行计划
1.父子关系
执行计划为树形结构。
树的每一个节点都代表一个操作,如,表访问、连接
或排序。
在各节点之间存在父子关系。
规则:
⏹父有多个子
⏹子只有一个父
⏹唯一没有父的操作是树的根
⏹父子关系用缩进来表示。
一个父的所有孩子缩进相同的字符数
⏹父在孩子的前面。
靠孩子最近的是他的父亲
下面是执行计划的一部分,
⏹操作1是树的根,它有三个孩子:2,5,和8
⏹操作2有两个孩子:3和4
⏹操作3和4没有孩子
⏹操作5有一个孩子:6
⏹操作6有一个孩子:7
⏹操作7没有孩子
⏹操作8有一个孩子:9
⏹操作9没有孩子
III.优化SQL
A.找出不理想的访问路径
目标:消耗资源最少,而消耗资源用逻辑读来衡量。
为何使用逻辑读度量?
⏹逻辑读是受制于CPU能力的操作,可以反映CPU的使用情况
⏹逻辑读可能导致物理读。
因此减少逻辑读,很可能会降低I/O 操作次数
⏹逻辑读数量可以很方便的获取到
1.经验法则:
⏹每个返回行少于5个逻辑读的访问路径比较好
⏹每个返回行10~15个逻辑读是正常
⏹每个返回行15~20个逻辑读很可能是低效的。
2.检查平均每行逻辑读数量的方法
a.使用SQL跟踪。
set autot trace
3.低效率的原因
a.条件列没有建立索引
b.提供了索引,但SQL语句的语法限制了索引使用
4.解决办法
a.选择性较强的SQL:使用索引访问比较高效
b.选择性较弱的SQL: 使用全表扫描比较高效
B.具有弱选择性的SQL语句
1.全表扫描
在所有的表上都可以进行全表扫描。
在执行计划中,TABLE ACCESS FULL操作
对应全表扫描。
在全表扫描的过程中,数据库引擎顺序读取所有数据块。
2.全索引扫描
当索引包含查询所需要的所有数据的时候,全表扫描可以用全索引扫描(full
index scan)替代。
因为索引数据通常比表数据小的多,可以减少逻辑读。
C.强选择性的SQL语句
1.索引访问
索引访问是最常用的访问路径。
要利用索引,需要在WHERE子句中至少应用
一个通过索引的限制条件。
a.等于条件与B-树索引
1.INDEX UNIQUE SCAN
用于唯一索引
SELECT * FROM t WHERE id = 6;
第一步,通过操作2的谓词条件,对列id上的条件使用索引t_pk得到rowid。
第二步,使用rowid来访问表T
2.INDEX RANGE SCAN
用于非唯一性索引。
和a的差别是根据限制条件抽取多个rowid
SELECT * FROM t WHERE n1 = 6;
b.范围条件和B-索引
对B-树索引来说,范围条件和非唯一索引上的等于条件是一样的,使用
INDEX RANGE SCAN操作。
对范围条件来说,索引唯一性是无关的。
总会返
回多个rowid。
SELECT * FROM t WHERE id BETWEEN6AND19;
c.IN条件
IN条件没有特定的访问路径。
在执行计划中,INLIST ITERATOR操作指出因为IN条件的原因部分执行计划被多次执行。
基本上,IN条件只是一系列的等于条件。
注意和索引和表访问相关的操作对IN列表中的每一个值执行了一次。
SELECT * FROM t WHERE id IN (6, 8, 9, 28);
d.like条件
1.SELECT name FROM t WHERE name like‘%张三%’
2.SELECT name FROM t WHERE name like‘张三%’
如果不是以通配符开头,LIKE条件和范围条件一样处理。
否则就要使用全表扫描或全索引扫描。
e.min/max函数和B-索引
1.不指定范围条件,INDEX FULL SCAN。
实际上不运行全索引扫描,仅得
到最左边或最右边的索引键
SELECT MIN(id) FROM t;
2.指定范围条件,INDEX RANGE SCAN(MIN/MAX),当查询条件对索引列
指定条件时使用
SELECT MIN(id) FROM t WHERE id > 42;
f.基于函数的索引
对索引列进行函数转换的时候,无法用到索引。
如果不能改写限制条件,只有在限制条件列上建立函数索引。
SQL:SELECT * FROM t WHERE upper(c1) = 'SELDON';
执行计划:
增加函数索引,CREATE INDEX i_c1_upper ON t (upper(c1));
新的执行计划:
逻辑读由500减少到了2个。
g.组合索引
带有多列的索引成为组合索引
作用:可以应用由and连接的多个SQL条件组成的限制。
注意:or不可以应用场景:多个and条件列上的唯一值较少,索引选择性不强,
SQL:SELECT/*+index(t i_n2)*/* FROM t WHERE n1=6AND n2=42AND n3=11;N2列上索引选择性不强
增加组合索引:
create index I_N123 on T (N1, N2, N3);
逻辑读由82减少到了4个。
h.只访问索引
当索引中包括处理查询所需要的所有数据时,可以执行只扫描索引操作。
SQL:SELECT n1 FROM t WHERE c1 LIKE'A%'
对于此类情况,要想使用只扫描索引操作,即使没有对某列应用限制条件也应该将其添加到索引中。
索引键中包含SQL语句中引用的所有列,而不止是Where条件中的列。
使用索引存储冗余数据来最小化逻辑读的量。
增加联合索引:CREATE INDEX t_n1_c1 ON t(c1,n1);
逻辑读由113个减少到了9个
IV.使用索引的注意事项
A.避免在索引列上使用计算
B.避免在索引列上使用函数
如:select * from table_name where to_char(number_column)=’12345’;
select * from table_name where number_column =to_number(’12345’);
C.like查询避免使用通配符%开头
D.使用not exists代替not in
1.select * from t1 a where id not in(select id form t2);
2.select * from t1 a where not exists(select 1 from t2 where t1.id=t2.id);
E.多个选择性不强的条件,建立组合索引
F.在查询列和条件列上建立组合索引
G.在进行排序的列上建立索引
1.select * from t1 order by n1 desc;
H.强制使用索引:使用提示(hint)。