index range scan,index fast full scan,index skip scan发生的条件

本文详细解析了Oracle数据库中不同类型的索引扫描方式,包括索引范围扫描、索引快速全扫描及索引跳跃式扫描等,并通过实验验证了各种扫描触发的条件。

源链接:https://blog.youkuaiyun.com/robinson1988/article/details/4980611

 

index range scan(索引范围扫描):

1.对于unique index来说,如果where 条件后面出现了<,> ,between ...and...的时候,那么就可能执行index range scan,如果where条件后面是=,那么就会执行index unique scan。

2.对于none unique index来说 如果where 条件后面出现了=,>,<,betweed...and...的时候,就有可能执行index range scan。

3.对于组合索引来说,如果where条件后面出现了组合索引的引导列,那么可能执行index range scan。

 

index fast full scan(索引快速全扫描):

如果select 语句后面中的列都被包含在组合索引中,而且where后面没有出现组合索引的引导列,并且需要检索出大部分数据,那么这个时候可能执行index fast full scan。index fast full scan 发生的条件:

1.必须是组合索引。2.引导列不在where条件中

 

index skip scan(索引跳跃式扫描)

当查询可以通过组合索引得到结果,而且返回结果很少,并且where条件中没有包含索引引导列的时候,可能执行index skip scan

索引跳跃式扫描发生的条件:

1.必须是组合索引。

2.引导列没有出现在where条件中

 

下面通过一个简单的实验验证一下上诉理论:

SQL> create table test as select * from dba_objects;

表已创建。

SQL> create unique index ind_id on test(object_id);    ind_id是唯一索引

索引已创建。

SQL> create index ind_owner on test(owner);             ind_owner是非唯一索引

索引已创建。

SQL> create index ooo on test(owner,object_name,object_type);  ooo是组合索引

索引已创建。

SQL> exec dbms_stats.gather_table_stats('ROBINSON','TEST');

PL/SQL 过程已成功完成。

SQL> set autot trace
SQL> select owner from test where object_id=10;
执行计划
----------------------------------------------------------
Plan hash value: 2544773305

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    11 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST   |     1 |    11 |     2   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | IND_ID |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

SQL> select owner from test where object_id<10;

已选择8行。
执行计划
----------------------------------------------------------
Plan hash value: 1361604213

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     7 |    77 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST   |     7 |    77 |     3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_ID |     7 |       |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

对于唯一索引,发生index range scan的时候就是返回多行记录,where 后面有 >,<,between ..and..

SQL> select owner from test where owner='SCOTT';

已选择13行。
执行计划
----------------------------------------------------------
Plan hash value: 2280863269

------------------------------------------------------------------------------
| Id  | Operation        | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |           |  2936 | 17616 |     7   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IND_OWNER |  2936 | 17616 |     7   (0)| 00:00:01 |
------------------------------------------------------------------------------

对于非唯一索引,即使where后面的限制条件是=,但是有可能返回多行,所以进行index range scan

SQL> select object_name,object_type from test where owner='ROBINSON';

已选择15行。
执行计划
----------------------------------------------------------
Plan hash value: 2845720098

 

-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |  2936 |   114K|    23   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| OOO  |  2936 |   114K|    23   (0)| 00:00:01 |
-------------------------------------------------------------------------

因为000不是唯一索引,而且where后面用到了索引ooo的引导列,所以进行index range scan.

SQL> select owner, object_name,object_type from test where object_name='EMP' ;
执行计划
----------------------------------------------------------
Plan hash value: 1799988433

-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |     2 |    80 |    19   (0)| 00:00:01 |
|*  1 |  INDEX SKIP SCAN | OOO  |     2 |    80 |    19   (0)| 00:00:01 |
-------------------------------------------------------------------------

因为查询所需要的信息可以通过索引ooo获得,并且where后面没有引导列owner,而且返回的行数很少(这里只有一行),所以CBO选择index skip scan,这里autotrace没有显示返回多少行,下面显示一下

SQL> set autot off
SQL> select owner, object_name,object_type from test where object_name='EMP' ;

OWNER                          OBJECT_NAME          OBJECT_TYPE
------------------------------ -------------------- -------------------
SCOTT                          EMP                  TABLE

SQL> select owner, object_name,object_type from test where object_type='INDEX';

已选择1701行。
执行计划
----------------------------------------------------------
Plan hash value: 3464522019

-----------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |  1721 | 68840 |    70   (3)| 00:00:01 |
|*  1 |  INDEX FAST FULL SCAN| OOO  |  1721 | 68840 |    70   (3)| 00:00:01 |
-----------------------------------------------------------------------------

因为查询所需的信息可以通过索引ooo获得,并且where后面没有引导列owner,而且返回的行数较多(1701行),所以CBO选择index fast full scan,这样避免了全表扫描。

转载于:https://www.cnblogs.com/wingler/p/8986224.html

Description 对象所有者 对象名称 耗费 基数 字节 SELECT STATEMENT, GOAL = ALL_ROWS 21,817 1,814 1,970,004 TABLE ACCESS BY INDEX ROWID WOTS RU_TRUST_RULE 3 1 18 INDEX RANGE SCAN WOTS IX_RU_TRUST_RULE_SALE_SYSTEM 1 50 INDEX RANGE SCAN WOTS FW_TRANSLATE_IX1 2 1 33 TABLE ACCESS BY INDEX ROWID WOTS AP_BUSINESS 1 1 115 INDEX SKIP SCAN WOTS AP_BUSINESS_IDX2 1 1 TABLE ACCESS FULL WOTS TP_TRADE_BUSINESS 5 1 101 HASH JOIN OUTER 21,817 1,814 1,970,004 HASH JOIN RIGHT OUTER 21,228 1,814 1,710,602 TABLE ACCESS FULL WOTS CA_RETURN_CAPITAL_ROUTER 4 293 7,618 HASH JOIN RIGHT OUTER 21,224 1,814 1,663,438 VIEW WOTSQUERY 3 1 104 NESTED LOOPS OUTER 3 1 130 TABLE ACCESS FULL WOTS AC_CREDIT_CARD_ACCOUNT 2 1 100 TABLE ACCESS BY INDEX ROWID WOTS AC_CREDIT_CARD_CHANNEL 1 1 30 INDEX UNIQUE SCAN WOTS PK_AC_CREDIT_CARD_CHANNEL 0 1 NESTED LOOPS OUTER 21,221 1,814 1,474,782 VIEW SYS 21,221 1,814 1,050,306 NESTED LOOPS OUTER 21,221 1,814 634,900 FILTER NESTED LOOPS OUTER 21,219 1,814 605,876 NESTED LOOPS OUTER 17,602 1,814 511,548 HASH JOIN OUTER 16,013 1,814 449,872 HASH JOIN OUTER 12,909 1,814 388,196 NESTED LOOPS OUTER 12,804 1,814 350,102 TABLE ACCESS BY INDEX ROWID WOTS TR_TRADE_BUSINESS 12,803 1,814 319,264 INDEX RANGE SCAN WOTS TR_TRADE_BUSINESS_IX6 333 60,843 TABLE ACCESS BY INDEX ROWID WOTS AC_PAYMENT_CHANNEL 1 1 17 INDEX UNIQUE SCAN WOTS PK_AC_PAYMENT_CHANNEL 0 1 INDEX FAST FULL SCAN WOTS IDX_AC_TRADE_ACCOUNT_2 105 85,721 1,800,141 VIEW WOTS AC_RETURN_ACCOUNT_LATEST 3,103 125,458 4,265,572 HASH JOIN RIGHT OUTER 3,103 125,458 7,151,106 TABLE ACCESS FULL WOTS AC_CURRENT_ACCOUNT 589 101,628 1,727,676 VIEW WOTS 2,062 125,458 5,018,320 WINDOW SORT PUSHED RANK 2,062 125,458 6,649,274 TABLE ACCESS FULL WOTS AC_PAYMENT_ACCOUNT 418 125,458 6,649,274 TABLE ACCESS BY INDEX ROWID WOTS TR_BUSINESS_RELATION 4 1 34 INDEX RANGE SCAN WOTS IDX_TR_BUSINESS_RELATION_1 3 1 TABLE ACCESS BY INDEX ROWID WOTS TR_TRADE_REQUEST 2 1 52 INDEX UNIQUE SCAN WOTS PK_TR_TRADE_REQUEST 1 1 TABLE ACCESS BY INDEX ROWID WOTS CA_SELLER_ACCOUNT 1 1 16 INDEX UNIQUE SCAN WOTS PK_CA_SELLER_ACCOUNT 0 1 TABLE ACCESS BY INDEX ROWID WOTS CC_REPAYMENT_REQUEST 0 1 234 INDEX UNIQUE SCAN WOTS PK_REPAYMENT_REQUEST 0 1 TABLE ACCESS FULL WOTS AC_CURRENT_ACCOUNT 589 101,628 14,532,804 查询sql的执行计划,分析一下慢在哪个地方,怎么优化?
最新发布
09-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值