Index Skip Scan were Introduced in Oracle 9i
Index Skip Scan improves index scan by non-prefix columns.
Skip scanning splits the composite index to be logically split into smaller subindexes.
The number of logical Subindexes is determined by number of distinct values of Initial column.
Skip scanning is advantage if there are few distinct values in leading column and many distinct values on non-leading key columns.
Skip scanning splits the composite index to be logically split into smaller subindexes.
The number of logical Subindexes is determined by number of distinct values of Initial column.
Skip scanning is advantage if there are few distinct values in leading column and many distinct values on non-leading key columns.
create table t as select * from all_objects;
create index t_ind on t(object_type,object_id);
exec dbms_stats.gather_table_stats(ownname=>USER,tabname=>'T',estimate_percent=>100,cascade=>true,method_opt=>'for all columns size 254');
scott@10G> select object_type,count(*)
2 from T
3 group by object_type;
OBJECT_TYPE COUNT(*)
------------------- ----------
CONSUMER GROUP 2
INDEX PARTITION 446
JAVA DATA 306
RULE 7
SCHEDULE 1
SEQUENCE 227
TABLE PARTITION 298
OPERATOR 57
PROCEDURE 131
WINDOW 2
LIBRARY 152
LOB 6
PACKAGE 895
PACKAGE BODY 836
PROGRAM 12
RULE SET 26
CONTEXT 5
JAVA RESOURCE 772
TYPE BODY 176
XML SCHEMA 25
DIRECTORY 5
JOB CLASS 2
MATERIALIZED VIEW 2
TRIGGER 261
FUNCTION 294
INDEX 2143
INDEXTYPE 10
JAVA CLASS 16420
SYNONYM 20110
TABLE 1948
VIEW 3761
WINDOW GROUP 1
CLUSTER 10
EVALUATION CONTEXT 14
JOB 11
TYPE 2013
create index t_ind on t(object_type,object_id);
exec dbms_stats.gather_table_stats(ownname=>USER,tabname=>'T',estimate_percent=>100,cascade=>true,method_opt=>'for all columns size 254');
scott@10G> select object_type,count(*)
2 from T
3 group by object_type;
OBJECT_TYPE COUNT(*)
------------------- ----------
CONSUMER GROUP 2
INDEX PARTITION 446
JAVA DATA 306
RULE 7
SCHEDULE 1
SEQUENCE 227
TABLE PARTITION 298
OPERATOR 57
PROCEDURE 131
WINDOW 2
LIBRARY 152
LOB 6
PACKAGE 895
PACKAGE BODY 836
PROGRAM 12
RULE SET 26
CONTEXT 5
JAVA RESOURCE 772
TYPE BODY 176
XML SCHEMA 25
DIRECTORY 5
JOB CLASS 2
MATERIALIZED VIEW 2
TRIGGER 261
FUNCTION 294
INDEX 2143
INDEXTYPE 10
JAVA CLASS 16420
SYNONYM 20110
TABLE 1948
VIEW 3761
WINDOW GROUP 1
CLUSTER 10
EVALUATION CONTEXT 14
JOB 11
TYPE 2013
36 rows selected.
So, splitting this Composite Index will result into 36 logical subindexes one for each object_type.
scott@10G> select *
2 from t
3 where object_id between 100 and 200;
100 rows selected.
Elapsed: 00:00:00.03
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 9300 | 106 (1)| 00:00:02 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 100 | 9300 | 106 (1)| 00:00:02 |
|* 2 | INDEX SKIP SCAN | T_IND | 99 | | 101 (1)| 00:00:02 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID">=100 AND "OBJECT_ID"<=200)
filter("OBJECT_ID"<=200 AND "OBJECT_ID">=100)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
28 consistent gets
0 physical reads
0 redo size
3890 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
100 rows processed
2 from t
3 where object_id between 100 and 200;
100 rows selected.
Elapsed: 00:00:00.03
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 9300 | 106 (1)| 00:00:02 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 100 | 9300 | 106 (1)| 00:00:02 |
|* 2 | INDEX SKIP SCAN | T_IND | 99 | | 101 (1)| 00:00:02 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID">=100 AND "OBJECT_ID"<=200)
filter("OBJECT_ID"<=200 AND "OBJECT_ID">=100)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
28 consistent gets
0 physical reads
0 redo size
3890 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
100 rows processed
Very interesting page.
ReplyDelete