SQL > create index test.ind_fun on test.testindex( upper (a));
索引已创建。
SQL > insert into testindex values ( ' a ' , 2 );
已创建 1 行。
SQL > commit ;
提交完成。
SQL > select /**/ /*+ RULE*/ * FROM test.testindex where upper (a) = ' A ' ;
A B
-- ----------
a 2
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = HINT: RULE
1 0 TABLE ACCESS ( FULL ) OF ' TESTINDEX '
(优化器选择了全表扫描)
-- ------------------------------------------------------------------
SQL > select * FROM test.testindex where upper (a) = ' A ' ;
A B
-- ----------
a 2
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = CHOOSE (Cost = 2 Card = 1 Bytes = 5 )
1 0 TABLE ACCESS ( BY INDEX ROWID) OF ' TESTINDEX ' (Cost = 2 Card =
1 Bytes = 5 )
2 1 INDEX (RANGE SCAN) OF ' IND_FUN ' (NON - UNIQUE ) (Cost = 1 Car
d = 1 )(使用了ind_fun索引)
SQL > set autotrace on
SQL > select * from test;
A
-- --------
1
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = CHOOSE
1 0 TABLE ACCESS ( FULL ) OF ' TEST '
Statistics
-- --------------------------------------------------------
0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
0 bytes sent via SQL * Net to client
0 bytes received via SQL * Net from client
0 SQL * Net roundtrips to / from client
0 sorts (memory)
0 sorts ( disk )
rows processed
![]()
SQL > set autotrace traceonly
SQL > select * from test.test;
![]()
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = CHOOSE
1 0 TABLE ACCESS ( FULL ) OF ' TEST '
![]()
Statistics
-- --------------------------------------------------------
0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
0 bytes sent via SQL * Net to client
0 bytes received via SQL * Net from client
0 SQL * Net roundtrips to / from client
0 sorts (memory)
0 sorts ( disk )
rows processed
SQL > create table test.testindex (a varchar ( 2 ),b number );
表已创建。
SQL > create index ind_cola on test.testindex(a);
索引已创建。
SQL > insert into test.testindex values ( ' 1 ' , 1 );
已创建 1 行。
SQL > commit ;
提交完成。
SQL > analyze table test.testindex compute statistics for all indexes;
表已分析。
SQL > set autotrace on ;
SQL > select /**/ /*+RULE */ * FROM test.testindex where a = ' 1 ' ;(使用基于rule的优化器,数据类型匹配的情况下)
A B
-- ----------
1 1
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = HINT: RULE
1 0 TABLE ACCESS ( BY INDEX ROWID) OF ' TESTINDEX '
2 1 INDEX (RANGE SCAN) OF ' IND_COLA ' (NON - UNIQUE )(使用了索引ind_cola)
�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D
SQL > select /**/ /*+RULE */ * FROM test.testindex where a = 1 ;(数据类型不匹配的情况)
A B
-- ----------
1 1
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = HINT: RULE
1 0 TABLE ACCESS ( FULL ) OF ' TESTINDEX ' (优化器选择了全表扫描)
![]()
SQL > select /**/ /*+ RULE */ * FROM test.testindex where upper (a) = ' A ' ;(使用了函数upper()在列a上);
A B
-- ----------
a 2
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = HINT: RULE
1 0 TABLE ACCESS ( FULL ) OF ' TESTINDEX ' (优化器选择全表扫描)
-- --------------------------------------------------------
![]()
创建基于函数的索引
SQL > create index test.ind_fun on test.testindex( upper (a));
索引已创建。
SQL > insert into testindex values ( ' a ' , 2 );
已创建1行。
SQL > commit ;
提交完成。
SQL > select /**/ /*+ RULE*/ * FROM test.testindex where upper (a) = ' A ' ;
A B
-- ----------
a 2
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = HINT: RULE
1 0 TABLE ACCESS ( FULL ) OF ' TESTINDEX '
(在RULE优化器下忽略了函数索引选择了全表扫描)
-- ---------------------------------------------------------
SQL > select * FROM test.testindex where upper (a)
= ' A ' ;
A B
-- ----------
a 2
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = CHOOSE (Cost = 2 Card = 1 Bytes = 5 )
1 0 TABLE ACCESS ( BY INDEX ROWID) OF ' TESTINDEX ' (Cost = 2 Card =
1 Bytes = 5 )
2 1 INDEX (RANGE SCAN) OF ' IND_FUN ' (NON - UNIQUE ) (Cost = 1 Car
d = 1 )(CBO优化器使用了ind_fun索引)
创建一个复合索引
SQL > create index ind_com on test.testindex(a,b);
索引已创建。
SQL > select /**/ /*+ RULE*/ * from test.testindex where a = ' 1 ' ;
A B
-- ----------
1 2
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = HINT: RULE
1 0 INDEX (RANGE SCAN) OF ' IND_COM ' (NON - UNIQUE )(条件列表包含前导列时使用索引ind_com)
SQL > select /**/ /*+ RULE*/ * from test.testindex where b = 1 ;
未选定行
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = HINT: RULE
1 0 TABLE ACCESS ( FULL ) OF ' TESTINDEX ' (条件列表不包括前导列是选择全表扫描)
-- ---------------------------------------------------------
SQL > select * from test.testindex where a = ' 1 ' ;
A B
-- ----------
1 2
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = CHOOSE (Cost = 1 Card = 1 Bytes = 5 )
1 0 TABLE ACCESS ( FULL ) OF ' TESTINDEX ' (Cost = 1 Card = 1 Bytes = 5 )
(表一共2行,选择比例为50 % ,所以优化器选择了全表扫描)
�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D
下面增加表行数
SQL > declare i number ;
2 begin
3 for i in 1 .. 100 loop
4 insert into test.testindex values (to_char(i),i);
5 end loop;
6 end ;
7 /
PL / SQL 过程已成功完成。
SQL > commit ;
提交完成。
SQL > select count ( * ) from test.testindex;
COUNT ( * )
-- --------
102
SQL > select * from test.testindex where a = ' 1 ' ;
A B
-- -- ----------
1 1
1 2
Execution Plan
SELECT STATEMENT Optimizer = CHOOSE (Cost = 1 Card = 1 Bytes = 5 )
1 0 INDEX (RANGE SCAN) OF ' IND_COM ' (NON - UNIQUE ) (Cost = 1 Card = 1 Bytes = 5 )
(表一共102行,选择比例为2 / 102 = 2 % ,所以优化器选择了索引扫描)
SQL > select * from test.testindex where a like ' 1% ' ;
A B
-- -- ----------
1 2
1 1
10 10
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
100 100
已选择13行。
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = CHOOSE (Cost = 1 Card = 13 Bytes = 52 )
1 0 TABLE ACCESS ( FULL ) OF ' TESTINDEX ' (Cost = 1 Card = 13 Bytes = 52 )
(表一共102行,选择比例为13 / 102 > 10 % ,优化器选择了全表扫描)
�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D
增加表行数
SQL > declare i number ;
2 begin
3 for i in 200 .. 1000 loop
4 insert into test.testindex values (to_char(i),i);
5 end loop;
6 end ;
7 /
PL / SQL 过程已成功完成。
SQL > commit ;
提交完成。
SQL > select count ( * ) from test.testindex;
COUNT ( * )
-- --------
903
SQL > select * from test.testindex where a like ' 1% ' ;
A B
-- -- ----------
1 2
1 1
10 10
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
100 100
1000 1000
已选择14行。
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = CHOOSE (Cost = 1 Card = 13 Bytes = 52 )
1 0 TABLE ACCESS ( FULL ) OF ' TESTINDEX ' (Cost = 1 Card = 13 Bytes = 52 )
(表一共903行,选择比例为14 / 903 < 5 % ,优化器选择了全表扫描,选择路径是错误的)
�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D
给表做分析
![]()
SQL > analyze table test.testindex compute statistics for table for all indexed c
olumns for all indexes;
表已分析。
SQL > select * from test.testindex where a like ' 1% ' ;
A B
-- -- ----------
1 2
1 1
10 10
100 100
1000 1000
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
已选择14行。
Execution Plan
-- --------------------------------------------------------
0 SELECT STATEMENT Optimizer = CHOOSE (Cost = 4 Card = 24 Bytes = 120 )
1 0 TABLE ACCESS ( BY INDEX ROWID) OF ' TESTINDEX ' (Cost = 4 Card =
24 Bytes = 120 )
2 1 INDEX (RANGE SCAN) OF ' IND_COLA ' (NON - UNIQUE ) (Cost = 2 Ca
rd = 24 )
(经过分析后优化器选择了正确的路径,使用了ind_cola索引)
�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D�D