跳跃式索引扫描的结构或算法特征

原创 2004年06月30日 12:45:00

2002年的时候有一天看到 oracle 支持索引的skip  scan ,也就是说

假设存在  index (a,b)

则查询 select * from table where b = ?  将能用到索引

从索引的结构想来,当时有些迷惑,对此进行过思考从而写下此文

 

跳跃式索引扫描的结构猜想

 

首先oracle 肯定不会是使用多个索引来掩盖问题的本质,那现在请允许我

假设索引(a,b,c)
我猜测是索引b或者c也有一个相临值之间的 “地址指针”
但他们之间是否具有树型结构不清楚
若不具有树结构则每次从该a 不同值进入从第一个b 值开始寻找符合条件数据
若具有树结构则每次进入一个a然后就迅速定位到符合条件b值
这样可能对每一个a值都要进入一次

我这样猜测
那么就可以通过控制a 或者 b值的数据分布和符合条件比例来逐步证明自己的猜测是否正确

举个例子
假设数据分布:
a b c
1 1 1
1 2 2
1 2 3
1 3 1
2 1 1
2 2 2
2 2 3

当查询 b = 2 的时候
不存在树结构: 先进入a=1, 然后顺序((也可2分法等方法,因为是排序好的)
)b=1,b=2,发现2条,不用比较3了,因为是有序的
存在树结构: 进入a= 1 ,迅速定位到2,然后找出和服条件记录

然后进入a=2 重复上面的过程

当查询 c = 3 的时候,先进入 a = 1,b=1,发现没有
进入 a=1,b=2,无树结构能快速定位到3(也可顺序可2分法,因为是排序好的),如此重复上面的步骤


由这个猜想
当数据量特别大并且数据可选择性很大的时候这种方式具有很大的优点
但这种猜测方式,假如 a 不具有相同值,而b 或者c 选择性比较小,那么这种结构的跳跃式扫描将是一种灾难

所以,oracle将根据统计分析结构来决定

但是,假如上述猜测不成立!
那我们可以从算法的角度来考虑

也就是说结构本身没有发生变化,但是在索引的搜索算法上可以从多个root ,branch进入进行扫描数据,这样当索引层次多的时候代价获取会高一些,但是不用维护结构的变化。

 

 

几个月后做了次测试

 

存在index(a,b)
当a的选择性不高的时候,oracle进行 跳跃式扫描的 优点明显
当a的选择性高的时候,跳跃式扫描失去了意义
既然有跳跃一说,就是说每次扫描的时候,会有一个入口进去,扫描,然后从新的入口进去,扫描……如此反复

这个入口,就是 a 的不同的值



SQL> create table t as select * from all_objects ;

表已创建。

SQL> create index t_index1 on t(owner,object_name);

索引已创建。
SQL> analyze table t compute statistics;

表已分析。

SQL> set autotrace on
SQL> select DATA_OBJECT_ID,created from t where object_name = 'DBA_EXTENTS';

DATA_OBJECT_ID CREATED
-------------- ----------
12-5月 -02
12-5月 -02

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=35 Card=2 Bytes=64)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=35 Card=2 Bytes
=64)

2 1 INDEX (SKIP SCAN) OF 'T_INDEX1' (NON-UNIQUE) (Cost=34 Ca
rd=1)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
26 consistent gets
0 physical reads
0 redo size
467 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
2 rows processed

SQL> drop index t_index1;

索引已丢弃。

SQL> create index t_index1 on t (object_name,owner);

索引已创建。

SQL> analyze table t compute statistics;

表已分析。

SQL> select * from t where owner = 'TEST';

OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED LAST_DDL_T TIMESTAMP STATUS T G S
---------- ---------- ------------------- ------- - - -
TEST A
30882 30882 TABLE
06-12月-02 06-12月-02 2002-12-06:17:35:38 VALID N N N

TEST B
33237 33237 TABLE
11-2月 -03 11-2月 -03 2003-02-11:10:07:49 VALID N N N

OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED LAST_DDL_T TIMESTAMP STATUS T G S
---------- ---------- ------------------- ------- - - -

TEST DBEXPERT_PLAN1
30333 30333 TABLE
02-12月-02 02-12月-02 2002-12-02:17:26:29 VALID N N N

TEST LMT
33468 33468 TABLE

OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED LAST_DDL_T TIMESTAMP STATUS T G S
---------- ---------- ------------------- ------- - - -
27-2月 -03 27-2月 -03 2003-02-27:09:22:18 VALID N N N

TEST LOGON_HISTORY
31284 TRIGGER
30-12月-02 30-12月-02 2002-12-30:19:02:08 VALID N N N

TEST MANLMT

OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED LAST_DDL_T TIMESTAMP STATUS T G S
---------- ---------- ------------------- ------- - - -
33469 33469 TABLE
27-2月 -03 27-2月 -03 2003-02-27:10:07:10 VALID N N N

TEST PLAN_TABLE
33482 33482 TABLE
03-3月 -03 03-3月 -03 2003-03-03:10:49:09 VALID N N N

OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED LAST_DDL_T TIMESTAMP STATUS T G S
---------- ---------- ------------------- ------- - - -
TEST SESSION_HISTORY
31287 31287 TABLE
30-12月-02 30-12月-02 2002-12-30:19:00:41 VALID N N N

TEST T
33485 33485 TABLE
03-3月 -03 03-3月 -03 2003-03-03:17:12:42 VALID N N N

OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED LAST_DDL_T TIMESTAMP STATUS T G S
---------- ---------- ------------------- ------- - - -

TEST TEST
33483 33483 TABLE
03-3月 -03 03-3月 -03 2003-03-03:10:52:08 VALID N N N

TEST TEST_INDEX
33484 33484 INDEX

OWNER OBJECT_NAME
------------------------------ ------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED LAST_DDL_T TIMESTAMP STATUS T G S
---------- ---------- ------------------- ------- - - -
03-3月 -03 03-3月 -03 2003-03-03:10:52:34 VALID N N N

已选择11行。

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=43 Card=927 Bytes=79
722)

1 0 TABLE ACCESS (FULL) OF 'T' (Cost=43 Card=927 Bytes=79722)

Statistics
----------------------------------------------------------
71 recursive calls
0 db block gets
450 consistent gets
0 physical reads
0 redo size
2264 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
11 rows processed

 

感谢 chao_ping 当时给出的一个例子

 

SELECT OWNER,OBJECT_ID FROM YAFENG WHERE object_name='DBA_TABLES'
16:44:01 scott@ORA9> /

OWNER OBJECT_ID
------------------------------------------------------------ ----------
PUBLIC 1813
SYS 1812

Elapsed: 00:00:00.15

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=11 Card=1 Bytes=22)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'YAFENG' (Cost=11 Card=1 Bytes=22)
2 1 INDEX (SKIP SCAN) OF 'IDX_YAFENG' (NON-UNIQUE) (Cost=10 Card=1)

12 consistent gets
16:44:02 scott@ORA9> select distinct owner from yafeng;

OWNER
------------------------------------------------------------
BIDDER
EACHPAY
OUTLN
PERFSTAT
PUBLIC
SCOTT
SYS
SYSTEM

8 rows selected.
12 consistent gets:

root block -> branch block(begin with bidder:no object_name like DBA_tables) ---one block gets
-> Branch block(begin with eachpay:no object_name like dba_tables) ---one block gets
-> Branch block(begin with outln:no object_name like dba_tables) --one block gets
-> Branch block(begin with perfstat:no object_name like dba_tables) ---one block gets
-> Branch block(begin with public:find one object named dba_tabes)->rowid-row (2 block gets)
-> Branch block(begin with scott:no object_name like dba_tables) --one block gets
-> Branch block(begin with system:no object_name like dba_tables) --one block gets
-> Branch block(begin with sys:no object_name like dba_tables) ->rowid-row(2 block gets)

 

 

 

 

 

 

索引——跳跃式扫描

索引跳跃式扫描(index skip scan)是ORACLE9i用来提高性能的新特性,对于使用复合索引的数据库应用程序意义尤为重大。      复合索引(又称为连接索引)是一个包含多个字段的索...
  • narutobing
  • narutobing
  • 2012年07月12日 14:25
  • 2010

索引扫描与索引查找的区别

 一、索引扫描 与表扫描类似,都是把索引从开始扫描到结束。   二、索引查找 会根据你查询的字符,定位到索引的局部位置,然后再开始查找,不用把整个索引全部扫描一遍,在效率上比索引...
  • whaxrl
  • whaxrl
  • 2015年09月16日 11:26
  • 840

第六章——根据执行计划优化性能(2)——查找表/索引扫描

前言:       在绝大部分情况下,特别是从一个大表中返回少量数据时,表扫描或者索引扫描并不是一种高效的方式。这些必须找出来并解决它们从而提高性能,因为扫描将遍历每一行,查找符合条件的数据,然后返...
  • DBA_Huangzj
  • DBA_Huangzj
  • 2013年03月18日 17:03
  • 7201

第一章1.2 算法的本质,5个特性与要求

算法的5个重要特性: ①有穷性: 一个算法必须总是在执行有穷步之后结束,且每一步都可在有穷时间内完成。 ②确定性:算法中的每条指令必须有确切的含义,不会产生二义性,并且对于相同的输入只能得出相同的输出...
  • dark_tone
  • dark_tone
  • 2016年09月22日 17:14
  • 493

SQL索引查找与索引扫描

本文导读:虽然都是通过索引取到相应数据,但是两者在过程上还是有区别的,索引扫描与表扫描差不多,都是把索引从开始扫描到结束,而索引查找就不一样了,会根据你查询的字符,定位到索引的局部位置,然后再开始查找...
  • RainyLin
  • RainyLin
  • 2017年11月20日 23:34
  • 277

几种索引扫描方式的比较

索引唯一性扫描(INDEX UNIQUE SCAN)(针对unique index的扫描)比索引范围扫描(INDEX UNIQUE SCAN)需要的逻辑读至少少1,这是因为索引唯一行扫描明确只有最多一...
  • seagal890
  • seagal890
  • 2014年06月22日 14:28
  • 1251

算法的五个特征

如此经典的问题,大学生考试的时候一定会考的,可
  • u011421608
  • u011421608
  • 2014年06月05日 10:46
  • 2223

Mysql索引扫描排序

使用索引扫描来做排序生成有序结果Mysql有两种操作可以用来生成有序结果: + 排序操作: 将查找出来的结果使用排序算法进行排序 + 按索引顺序扫描: ORDER BY语句后跟着一个被索引的列,如...
  • u013298300
  • u013298300
  • 2016年09月02日 17:30
  • 501

北大ACM试题1009之连续跳跃编码

上一篇说到直观解法走到了死胡同,默默的去看了一下大神的思路(感谢大神,很多题目她都有思路和解法,还是个美女!!!博客地是http://blog.csdn.net/lyy289065406)。她提到算法...
  • heroskaka
  • heroskaka
  • 2015年04月02日 14:35
  • 462

很好的人脸识别特征脸分析

人脸识别之特征脸方法(Eigenface) zouxy09@qq.com http://blog.csdn.net/zouxy09         因为需要,花了一点时间写了下经典的基于特征脸...
  • huangshanxiaoshitou
  • huangshanxiaoshitou
  • 2016年05月13日 11:08
  • 679
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:跳跃式索引扫描的结构或算法特征
举报原因:
原因补充:

(最多只允许输入30个字)