Oracle sql 性能优化调整(26/27/28/29)

本文详细介绍了Oracle SQL性能优化中的索引操作,包括索引唯一扫描和索引范围查询,以及如何根据索引选择基础表。讨论了在多个平等索引存在时的处理方式,并分析了等式比较和范围比较对查询路径的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

26.       索引的操作

 

ORACLE对索引有两种访问模式.

 

索引唯一扫描 ( INDEX UNIQUE SCAN)

 

大多数情况下, 优化器通过WHERE子句访问INDEX.

 

例如:

表LODGING有两个索引 : 建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER.

 

 

 

SELECT *

FROM LODGING

WHERE LODGING = ‘ROSE HILL’;

 

   在内部 , 上述SQL将被分成两步执行, 首先 , LODGING_PK 索引将通过索引唯一扫描的方式被访问 , 获得相对应的ROWID, 通过ROWID访问表的方式 执行下一步检索.

   如果被检索返回的列包括在INDEX列中,ORACLE将不执行第二步的处理(通过ROWID访问表). 因为检索数据保存在索引中, 单单访问索引就可以完全满足查询结果.

   下面SQL只需要INDEX UNIQUE SCAN 操作.

        

        SELECT LODGING

        FROM  LODGING

WHERE LODGING = ‘ROSE HILL’;

 

  索引范围查询(INDEX RANGE SCAN)

      适用于两种情况:

1.       基于一个范围的检索

2.       基于非唯一性索引的检索

 

 例1:

 

      SELECT LODGING

      FROM  LODGING

WHERE LODGING LIKE ‘M%’;

 

WHERE子句条件包括一系列值, ORACLE将通过索引范围查询的方式查询LODGING_PK . 由于索引范围查询将返回一组值, 它的效率就要比索引唯一扫描

低一些.

 

例2:

 

      SELECT LODGING

      FROM  LODGING

WHERE MANAGER = ‘BILL GATES’;

 

  这个SQL的执行分两步, LODGING$MANAGER的索引范围查询(得到所有符合条件记录的ROWID) 和下一步同过ROWID访问表得到LODGING列的值. 由于LODGING$MANAGER是一个非唯一性的索引,数据库不能对它执行索引唯一扫描.

 

  由于SQL返回LODGING列,而它并不存在于LODGING$MANAGER索引中, 所以在索引范围查询后会执行一个通过ROWID访问表的操作.

 

  WHERE子句中, 如果索引列所对应的值的第一个字符由通配符(WILDCARD)开始, 索引将不被采用.

 

 SELECT LODGING

      FROM  LODGING

WHERE MANAGER LIKE ‘%HANMAN’;

 

 在这种情况下,ORACLE将使用全表扫描.

27.       基础表的选择

 

基础表(Driving Table)是指被最先访问的表(通常以全表扫描的方式被访问). 根据优化器的不同, SQL语句中基础表的选择是不一样的.

如果你使用的是CBO (COST BASED OPTIMIZER),优化器会检查SQL语句中的每个表的物理大小,索引的状态,然后选用花费最低的执行路径.

如果你用RBO (RULE BASED OPTIMIZER) , 并且所有的连接条件都有索引对应, 在这种情况下, 基础表就是FROM 子句中列在最后的那个表.

举例:

     SELECT A.NAME , B.MANAGER

     FROMWORKER A,

             LODGING B

     WHEREA.LODGING = B.LODING;

由于LODGING表的LODING列上有一个索引, 而且WORKER表中没有相比较的索引, WORKER表将被作为查询中的基础表.

 

28.       多个平等的索引

当SQL语句的执行路径可以使用分布在多个表上的多个索引时, ORACLE会同时使用多个索引并在运行时对它们的记录进行合并, 检索出仅对全部索引有效的记录.

在ORACLE选择执行路径时,唯一性索引的等级高于非唯一性索引. 然而这个规则只有

当WHERE子句中索引列和常量比较才有效.如果索引列和其他表的索引类相比较. 这种子句在优化器中的等级是非常低的.

如果不同表中两个想同等级的索引将被引用, FROM子句中表的顺序将决定哪个会被率先使用. FROM子句中最后的表的索引将有最高的优先级.

如果相同表中两个想同等级的索引将被引用, WHERE子句中最先被引用的索引将有最高的优先级.

举例:

     DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引.

     SELECT ENAME,

     FROM EMP

     WHERE DEPT_NO = 20

     AND EMP_CAT = ‘A’;

这里,DEPTNO索引将被最先检索,然后同EMP_CAT索引检索出的记录进行合并. 执行路径如下:

 

TABLE ACCESS BY ROWID ON EMP

    AND-EQUAL

        INDEX RANGE SCAN ON DEPT_IDX

        INDEX RANGE SCAN ON CAT_IDX

 

29.        等式比较和范围比较

     当WHERE子句中有索引列, ORACLE不能合并它们,ORACLE将用范围比较.

 

     举例:

     DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引.

     SELECT ENAME

     FROM EMP

     WHERE DEPTNO > 20

     AND EMP_CAT = ‘A’;

    

     这里只有EMP_CAT索引被用到,然后所有的记录将逐条与DEPTNO条件进行比较. 执行路径如下:

     TABLE ACCESS BY ROWID ON EMP

           INDEX RANGE SCAN ON CAT_IDX

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值