Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1142446
  • 博文数量: 231
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 2662
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-03 16:35
个人简介

学无止境

文章分类

全部博文(231)

文章存档

2014年(7)

2013年(103)

2011年(11)

2010年(53)

2009年(57)

分类: Oracle

2010-06-21 15:14:50

实验环境:       
zhsy_test表有20万行记录。
id选择性很好,该字段具有唯一性。a3字段选择性不好,只有3种值。
 
SQL语句:
select * from zhsy_test where id<1000 and a3='瘦弱';
select * from zhsy_test where a3='瘦弱' and id<1000;
index语句:
create index zh_id_ind on zhsy_test(id);
drop  index zh_id_ind;
create index zh_ida3_ind on zhsy_test(id,a3);
drop index zh_ida3_ind;
create index zh_a3id_ind on zhsy_test(a3,id);
drop index zh_a3id_ind;
 
先将结论写在前面:

1.查询条件有多个字段时,组合索引,比只有其中一个字段的索引,具有更高的效率。
2.组合索引中,字段的顺序对执行计划有很大的影响。一般来说,应该把选择性强的字段放在前面。
3.SQL语句中WHERE后面所带条件的前后顺序,如条件中 A AND B与 B AND A,和组合索引中字段顺序没有关系。
4.当查询选择性较好的字段时,在组合索引字段不多的情况下,和单个字段索引的开销几乎相同。
5.组合索引中的索引顺序对条件字段有很大影响,如果查询条件中只有1个字段,该字段的选择性很好,但是在组合索引中,它并不位于第一位,在未对表分析之前,执行计划可能
还是会走全表扫描,对表进行了分析之后,才会走跳跃索引扫描,并且成本比顺序好的组合索引大得多。

实验过程:
1.只创建ID字段上的索引:create index zh_id_ind on zhsy_test(id);       
 
trace内容:
已选择20行。
已用时间:  00: 00: 00.04
执行计划
----------------------------------------------------------
Plan hash value: 2641874720
-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |    54 |  3294 |    70   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| ZHSY_TEST |    54 |  3294 |    70   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | ZH_ID_IND |    71 |       |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("A3"='瘦弱')
   2 - access("ID"<1000)
Note
-----
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         65  consistent gets
          0  physical reads
          0  redo size
       1389  bytes sent via SQL*Net to client
        396  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         
         
2.只创建组合索引,顺序为id,a3
 
trace内容:       
已选择20行。
已用时间:  00: 00: 00.04
执行计划
----------------------------------------------------------
Plan hash value: 4248746236
-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |    54 |  3294 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZHSY_TEST   |    54 |  3294 |     3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | ZH_IDA3_IND |     1 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("A3"='瘦弱' AND "ID"<1000)
       filter("A3"='瘦弱')
Note
-----
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         24  consistent gets
          0  physical reads
          0  redo size
       1519  bytes sent via SQL*Net to client
        396  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         20  rows processed
3.只创建组合索引,顺序为a3,id
 
trace内容:
已选择20行。
已用时间:  00: 00: 00.04
执行计划
----------------------------------------------------------
Plan hash value: 2050955217
-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |    20 |  1220 |    22   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZHSY_TEST   |    20 |  1220 |    22   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | ZH_A3ID_IND |    20 |       |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("A3"='瘦弱' AND "ID"<1000)
Note
-----
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         25  consistent gets
          0  physical reads
          0  redo size
       1519  bytes sent via SQL*Net to client
        396  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         20  rows processed
        
        
        
4.对调条件位置。SQL语句变成如下:
 select * from zhsy_test where a3='瘦弱' and id<1000;
执行计划没有发生变化。       
 
trace内容:
已选择20行。
已用时间:  00: 00: 00.04
执行计划
----------------------------------------------------------
Plan hash value: 2050955217
-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |    20 |  1220 |    22   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZHSY_TEST   |    20 |  1220 |    22   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | ZH_A3ID_IND |    20 |       |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("A3"='瘦弱' AND "ID"<1000)
Note
-----
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         25  consistent gets
          0  physical reads
          0  redo size
       1519  bytes sent via SQL*Net to client
        396  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         20  rows processed        
        
        
5.重新建回条件2中的组合索引,顺序为id,a3
 
trace内容:
已选择20行。
已用时间:  00: 00: 00.04
执行计划
----------------------------------------------------------
Plan hash value: 4248746236
-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |    54 |  3294 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZHSY_TEST   |    54 |  3294 |     3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | ZH_IDA3_IND |     1 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("A3"='瘦弱' AND "ID"<1000)
       filter("A3"='瘦弱')
Note
-----
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         24  consistent gets
          0  physical reads
          0  redo size
       1519  bytes sent via SQL*Net to client
        396  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         20  rows processed        
        
6.只查询ID字段,只见ID字段上索引。 select * from zhsy_test where id<1000;
 
trace内容:
已选择61行。
已用时间:  00: 00: 00.28
执行计划
----------------------------------------------------------
Plan hash value: 2641874720
-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |    61 |  3721 |    60   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZHSY_TEST |    61 |  3721 |    60   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | ZH_ID_IND |    61 |       |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID"<1000)
Note
-----
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         68  consistent gets
          0  physical reads
          0  redo size
       3452  bytes sent via SQL*Net to client
        429  bytes received via SQL*Net from client
          6  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         61  rows processed        
        
7.只有联合索引,只查询ID字段。
执行计划的开销与只有ID字段索引的开销相同。
 
trace内容:
已选择61行。
已用时间:  00: 00: 00.20
执行计划
----------------------------------------------------------
Plan hash value: 4248746236
-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |    61 |  3721 |    60   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZHSY_TEST   |    61 |  3721 |    60   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | ZH_IDA3_IND |    61 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID"<1000)
Note
-----
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         68  consistent gets
          0  physical reads
          0  redo size
       3452  bytes sent via SQL*Net to client
        429  bytes received via SQL*Net from client
          6  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         61  rows processed        
        
        
8.只建立联合索引,索引顺序为a3,id,查询条件只有id
尽管ID字段的选择性很好,但是仍旧走了全表扫描,没有用到索引。
已选择61行。
 
trace内容:
已用时间:  00: 00: 00.23
执行计划
----------------------------------------------------------
Plan hash value: 3670929120
-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |    71 |  4331 |   251   (2)| 00:00:04 |
|*  1 |  TABLE ACCESS FULL| ZHSY_TEST |    71 |  4331 |   251   (2)| 00:00:04 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("ID"<1000)
Note
-----
   - dynamic sampling used for this statement

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1136  consistent gets
          0  physical reads
          0  redo size
       3263  bytes sent via SQL*Net to client
        429  bytes received via SQL*Net from client
          6  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         61  rows processed        
        
        
对表进行了分析之后,才走了跳跃索引扫描,并且成本还是比顺序要id,a3的组合索引大得多。
已选择61行。
已用时间:  00: 00: 00.21
执行计划
----------------------------------------------------------
Plan hash value: 1085764453
-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |    48 |  1536 |   100   (0)| 00:00:02 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZHSY_TEST   |    48 |  1536 |   100   (0)| 00:00:02 |
|*  2 |   INDEX SKIP SCAN           | ZH_A3ID_IND |    49 |       |    51   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID"<1000)
       filter("ID"<1000)

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         82  consistent gets
          0  physical reads
          0  redo size
       3452  bytes sent via SQL*Net to client
        429  bytes received via SQL*Net from client
          6  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         61  rows processed
阅读(2774) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~