Oracle⼤数据查询优化
(1) IS NULL 与 IS NOT NULL 不能⽤null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列的情况下,只要这些列中有⼀列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提⾼性能。任何在where⼦句中使⽤is null或is not null的语句优化器是不允许使⽤索引的。
(2) 联接列 对于有联接的列,即使最后的联接值为⼀个静态值,优化器是不会使⽤索引的。⽐如下⾯的sql语句 select * from oil where
oil_name||’ '||oil_id =‘胜坨 shengtuo’;
要查询油⽥为“胜坨 shengtuo”的油⽥的数据,假设在oil_id列已经建了索引,此sql语句虽然也能实现正确的查询,但系统优化器对基于oil_id创建的索引却没有使⽤。如果改为以下的sql语句 select * from oil where oil_name =‘胜坨’and oil_id= ‘shengtuo’;
Oracle系统就可以采⽤基于oil_id创建的索引。
(3) 带通配符(%)的like语句
同样以上⾯的例⼦来看这种情况。⽬前的需求是这样的,要求在oil表中查询名称中包含胜坨的油。可以采⽤如下的查询SQL语句:select * from employee where oil_name like ‘%胜坨%’; 在以上sql语句中通配符(%)在搜寻词⾸出现,所以Oracle系统不使⽤oil_id的索引。不过在很多情况下可能⽆法避免这种情况,但是需要了解的是如此使⽤通配符会降低查询速度。不过当通配符出现在字符串的其它位置时,优化器就可以利⽤索引了,例如以下的查询就可以利⽤索引: select * from employee where oil_name like ‘胜坨%’;
(4) Order by语句 order by语句决定了Oracle如何将返回的查询结果排序。order by语句对要排序的列没有什么特别的限制,也可以将函数加⼊列中(像联接或者附加等)。任何在order by语句的⾮索引项或者有计算表达式都将降低查询速度。 仔细检查order by语句以出⾮索引项或者表达式,它们会降低性能。解决这个问题的办法就是重写order by语句以使⽤索引,也可以为所使⽤的列建⽴另外⼀个索引,同时应绝对避免在order by⼦句中使⽤表达式。
(5) NOT 在查询中,我们经常在where⼦句使⽤⼀些逻辑表达式,如⼤于、⼩于、等于以及不等于等等,也会⽤到and(与)、or(或)以及not(⾮)。NOT可⽤来对任何逻辑运算符号取反,⽐如… where not (oil_id=‘shengtuo’) 如果要使⽤NOT,则应在取反的短语前⾯加上括号,并在短语前⾯加上not运算符。not运算符包含在另外⼀个逻辑运算符中,这就是不等于(<>)运算符。也可以说,即使不在查询where⼦句中显式地加⼊not词,not仍在运算符中。
sql语句优化方式
看下⾯两条sql语句:
select * from oil where productoil <>3000; select * from oil where productoil <3000 or productoil >3000;
虽然这两种查询的结果⼀样,但是第⼆种查询⽅案会⽐第⼀种查询⽅案更快些。第⼆种查询允许Oracle对productoil列使⽤索引,⽽第⼀种查询则不能使⽤索引。
(6) IN和EXISTS
在查询中,我们也经常会⽤到两列进⾏⽐较的情况,最简单的⽅法是在where句⼦中使⽤⼦查询,⽽这种⼦查询⼀般有两种形式。 ⼀种是利⽤in操作符:… where column in (select * from …where …); 另⼀种是使⽤exist操作符:… where exists (select ‘X’ from …where …);
对于这两种格式的⼦查询语句,⼀般都会使⽤第⼀种是⽤in操作符的查询,因为这种语句⽐较容易些,也很直观,但实际上却是第⼆种格式的⼦查询效率会更⾼。在Oracle中可以将⼏乎所有的in操作符⼦查询改写为使⽤exists的⼦查询。 第⼆种格式中,⼦查询以‘select
‘X’’开始。运⽤exists⼦句不管⼦查询从表中抽取什么数据它只查看where⼦句的特点,这样优化器就不必遍历整个表⽽仅根据索引就可完成⼯作(这⾥假定在where语句中使⽤的列存在索引)。相对于IN
⼦句来说,exists使⽤相连⼦查询,构造起来要⽐in⼦查询困难⼀些。 通过使⽤exists,Oracle系统会⾸先检查主查询,然后运⾏⼦查询直到到第⼀个匹配项,这就节省了时间。Oracle系统在执⾏in⼦查询时,⾸先执⾏⼦查询,并将获得的结果列表存放在⼀个加了索引的临时表中。在执⾏⼦查询之前,系统先将主查询挂起,待⼦查询执⾏完毕,存放在临时表中以后再执⾏主查询。这也就是使⽤exists⽐使⽤in通常查询速度快的原因。
---------------------
|          临时表        |
---------------------
⽬前⼤部分使⽤Oracle作为数据库的系统数据量都⽐较庞⼤,在使⽤时我们经常会⽤到有多个表关联的情况,⽽且这些表⼤部分都⽐较庞⼤,但是当进⾏关联的时候却发现某⼀个表或⼏个表关联之后得到的结果集很⼩⽽且查询这个结果集的速度也⾮常快,那么这时候我们就可以考虑在Oracle中创建“临时表”。这样在⼯程中多次⽤到这些数据时直接查询临时表的速度要快很多,⽽当⽤完之后表中的数据就没⽤了,⽽且Oracle的临时表创建之后基本不占⽤表空间。 与使⽤永久表不同,添加或者更改临时表中的数据并不会⽣成重做⽇志条⽬,但是,它会⽣成撤销⽇志条⽬。永久表与临时表之间的另⼀项区别是⽚段的分配。临时表使⽤临时⽚段,并且在表中实际插⼊数据之前,不会向表分配临时⽚段。
ORACLE数据库系统的临时表有两种,⼀种是事务型临时表,⼀种是会话型临时表。事物型临时表是当⼀个事务结束时清空临时表的内容;⽽会话型临时表就当⼀个会话中断或者被重新连接时数据表的内容就会清空了。ORACLE数据库在清除临时表时,只清除数据,⽽不清楚临时表的本⾝。ORACLE还提供了⼀种更加细分的事务型临时表。⼀个会话中,可能有多个事务。也就是说,ORACLE清空临时型数据表的时间更加细腻,可以根据同⼀个会话中的不同事务来清空临时表。另外还要说明的⼀点就是,ORACLE的会话型临时中的内容对于各个⽤户来说,内容都是独⽴的。具体的说,就是各个⽤户在会话的过程中,都可以往⼀张临时表中存储数据;但是⽤户查询临时表中的数据的时候,只能够查询到⾃⼰所创建的内容,⽽不能看到其他⽤户所增加的记录。这对于临时表的安全性来说,是⾮常有保障的。临时表也有局限性,⽐如:
(1) 临时表只在当前连接内有效;
(2) 临时表不建⽴索引,所以如果数据量⽐较⼤或进⾏多次查询时,不推荐使⽤;
(3) 数据处理⽐较复杂的时候时较快,反之视图快点。
---------------------
|          总结          |
-
--------------------
综上所述,在进⾏简单查询时,充分利⽤索引,并合理的优化SQL语句来有效的利⽤索引,可以减少响应时间。⽽在⼯程中利⽤临时表减少数据的访问量、提⾼数据库操作的效率,从⽽减少响应时间。但是以上的优化⽅法都是作为参考⽤的,优化必须随着系统应⽤情况的变化和数据量的变化⽽调整,灵活地采取优化⼿段才能有效地提⾼系统效率。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。