Oracle SQL的优化(1)

发表于:2007-06-22来源:作者:点击数: 标签:
1、在Oracle中有两种操作可以直接访问Table (1)Table Access Full --为了优化全表扫描的 性能 ,Oracle在每次 数据库 读取中都会读取多个数据块; --只要查询中没有where子句,Oracle就会采用全表扫描。 (2)Table Access by RowID(基于RowID的访问) --RowID

   

1、在Oracle中有两种操作可以直接访问Table
   (1)Table Aclearcase/" target="_blank" >ccess Full
      --为了优化全表扫描的性能,Oracle在每次数据库读取中都会读取多个数据块;

      --只要查询中没有where子句,Oracle就会采用全表扫描。
   (2)Table Access by RowID(基于RowID的访问)
      --RowID记录了数据行的物理存储位置;
      --Oracle使用索引将数据值与RowID相关联,从而与数据物理位置相关联。
2、提示:在select关键字之后使用/*+... */

3、使用Index:
   (1)Index unique scan
 select * from bookshelf where title='WTL'
 假设在title列上有唯一索引,则这个语句的执行方式为:
            a)首先通过insex unique scan操作访问title列索引;
     b)从索引返回与title值'WTL'相匹配的RowID值,然后利用此RowID值
       通过Table Access by RowID操作来查询BookShelf表。
   (2)Index range scan
        如果基于一个值的范围查询或者利用一个非唯一索引进行查询,则可以使用index range
      scan操作对索引进行查询。由于index range scan操作需要从索引中读取多个值,所以它的
      效率要比index unique scan低。
          假设emp表的ename上有一个非唯一索引idx_emp_ename,如果在查询的where子句中给出
      ename的限定条件,则可能会执行idx_emp_ename索引的index range scan操作,应为ename上
      的这和索引是一个非唯一性索引,所以数据库不能在该索引上执行index unique scan操作,
      即便是ename等于查询中的单个值也不行,即...where ename='GLEDESON' 和
      ...where ename like 'G%'都是执行index range scan 操作的。
          注意:如果在like条件中的开头使用了通配符则查询将不会使用索引(如:like '%M%')
                来解决这个查询。
4、使用索引的注意事项:
   (1)如果设置了一个索引列等(=)一某个值,则将使用index range scan操作
             |--唯一索引(unique index)
      *索引--|
             |--非唯一索引(non-unique index)

   (2)要使用一个索引不一定要给出明确的值,index range scan操作可为值的范围扫描一个索引,具
      体的操作符有"<"、">"、"like",注意:不要在like算式的开头使用通配符!!
                 |--索引的全表扫描
      *全表扫描--|
                 |--表的全表扫描
   (3)如果在where条件中使用了函数,则不会使用索引,除非索引是基于函数的!
   (4)在查询条件中使用了is null、is not null则不会使用索引。(null值是不存在索引中的)
      *在大多数情况下,执行全表扫描将会比执行用索引返回的所有值执行索引扫描更为有效!
   (5)如果在查询条件中使用了"!="操作将不会使用索引,"<>"也不会。
   (6)使用not in、in操作符也不会使用索引,在Oracle中,几乎所有的not in、in操作都可以
      用not exists、exists来代替。...where exists(select 'x' from ...where ...)
      *使用exists子句,不管从子查询中抽取什么数据,它只会查看where子句。这样优化器就
       不会遍历整个表而仅根据索引就可以完成工作(这里假设where子句中的列上使用了index).
       通过使用exists,Oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹
       配项,这样就节省了时间。Oracle在执行in查询时,首先执行子查询,并将获得的结果列
       表存放到一个加了索引的临时表中,在执行子查询之前,先将主查询挂起,待子查询执行
       完毕存放到临时表中以后再执行主查询,这就是使用exists比使用in通常查询速度快的原
       因。
   (7)如果设置了复合索引的首列等于某个值,则使用该索引。
      *在复合索引中,Oracle9i之前,只有在限定条件中使用了复合索引的首列,才会使用该索
       引,但Oracle9i之后,索引的跳跃扫描特性允许优化器潜在地使用连接索引,即使复合索
       引的首列没有出现在where子句中也是如此!
   (8)如果选择了一个索引列的max或min函数,则优化器会使用此索引来快速地找到列的最大最小
      值。
   (9)索引的选择性:假设一个表中有100行,其中的一列(这列上有索引)中不重复的纪录有80个,
      也就是说有20行纪录有重复,则这个索引的选择性为80/100=0.80,即这列上的索引的选择
      性是80%,选择性越高,列中每个不同的值返回的行的数目就越少。
          如果使用的优化模式是CBO,并且索引是经过分析的,则优化程序就会考虑索引的选择
      性来判断使用索引是否会降低执行查询的成本。

原文转自:http://www.ltesting.net