|
Re: biti 哪能告诉我范围扫描差异在哪里?
我这里说的范围扫描 确切地说应该说 范围查询
因为范围查询是从一个入口点进去找到 叶子,然后从叶子之间的指针逐个找下去,如果碰巧该范围中有一段特别多的数据那将 搜索大量的数据
而如果是符合索引的两个字段条件都是等于并且满足条件的结果集比较小,那它是直接从 索引的枝上定位到相关叶子,则问题不是很大。
这是因为 a,b 两个字段的索引的key是存储在一起的,不存在先过滤一遍a再过滤一遍b的问题。也就是说,如果是符合索引,我们假定存在数字 a = 1000, b为 1..1000000 的记录。总记录条数为100万条,b是唯一的。若a做前导列的索引(a,b)。 实际上,如果查询总是同时存在 a,b 的等于条件,则效果就相当于 1000*100万 + 1..100万 这样的100万个值的单个字段做索引。
我再重复一遍我上面做过的实验,希望你仔细看一看!
SQL> desc t
Name Null? Type
----------------------------------------- -------- ----------------------------
OWNER VARCHAR2(30)
OBJECT_NAME VARCHAR2(128)
SUBOBJECT_NAME VARCHAR2(30)
OBJECT_ID NUMBER
DATA_OBJECT_ID NUMBER
OBJECT_TYPE VARCHAR2(18)
CREATED DATE
LAST_DDL_TIME DATE
TIMESTAMP VARCHAR2(19)
STATUS VARCHAR2(7)
TEMPORARY VARCHAR2(1)
GENERATED VARCHAR2(1)
SECONDARY VARCHAR2(1)
SQL> update t set owner = 'sys';
481216 rows updated.
SQL> commit;
Commit complete.
SQL> update t set OBJECT_ID = rownum;
481216 rows updated.
SQL> commit;
Commit complete.
SQL> create index t_ind12 on t(owner,object_id);
Index created.
SQL> set autotrace traceonly
SQL> select * from t where owner = 'sys' and object_id = 12345;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T'
2 1 INDEX (RANGE SCAN) OF 'T_IND12' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets
2 physical reads
0 redo size
1156 bytes sent via SQL*Net to client
499 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> create index t_ind21 on t(object_id,owner);
Index created.
SQL> select * from t where owner = 'sys' and object_id = 12345;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T'
2 1 INDEX (RANGE SCAN) OF 'T_IND21' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets
2 physical reads
0 redo size
1156 bytes sent via SQL*Net to client
499 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL>
在下面这个例子中 对于前导列a字段来说,恰好 'sys' 满足 > 'a' 这个条件,但是一开始你可能并不清楚会有这么多的相同的满足 >'a' 的值,这不过是举个例子,比如a换做数字类型,恰好大量数字a = 100,你查询一个 a between 99 and 100,你可能并不会认为大量记录在里面,但是实际上却还不如全表扫描。
SQL> select * from t where owner > 'a';
481216 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T'
2 1 INDEX (RANGE SCAN) OF 'T_IND12' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
70913 consistent gets
1245 physical reads
0 redo size
29217583 bytes sent via SQL*Net to client
353390 bytes received via SQL*Net from client
32083 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
481216 rows processed |
|