写一条SQL,使它通过全表扫描方式的效率优于索引访问,分别给出各自的执行计划。...

一、实验说明:

  操作系统:redhat 5.4 x86

  数据库:oracle 11g R2

  该实验通过建立一张规则表和一张不规则表,对这两张表分别使用全表扫描和索引访问,重点在于说明全表扫描的效率也可以优于索引访问。

二、实验具体步骤:

  2.1、创建一张规则表jack_test和一张不规则表echo_test。

 1 SQL> create table jack_test(x int,y varchar2(2000));   --创建jack_test表      
 2 
 3 Table created.
 4 
 5 SQL> begin 
 6   2    for i in 1..100000
 7   3    loop
 8   4       insert into jack_test values(i,rpad(dbms_random.random,75,'*'));
 9   5    end loop;
10   6   commit;
11   7  end;
12   8  /
13 
14 PL/SQL procedure successfully completed.
15 
16 SQL> alter table jack_test add constraint jack_pks primary key(x);
17 
18 Table altered.
19 
20 SQL> create table echo_test nologging                --创建echo_test表,并随机插入数据 
21   2    as
22   3      select x,y from jack_test
23   4   order by y
24   5  /
25 
26 Table created.
27 SQL> alter table echo_test add constraint echo_pk primary key(x);
28 
29 Table altered.

  2.2、比较对规则表用全表扫描与索引访问:

 1 SQL> set timing on;
 2 SQL> set linesize 200;
 3 SQL> set autotrace traceonly;
 4 SQL> select * from jack_test where x between 20000 and 40000;
 5 
 6 20001 rows selected.
 7 
 8 Elapsed: 00:00:00.23
 9 
10 Execution Plan
11 ----------------------------------------------------------
12 Plan hash value: 3796984134
13 
14 -------------------------------------------------------------------------------
15 | Id  | Operation      | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
16 -------------------------------------------------------------------------------
17 |   0 | SELECT STATEMENT  |          | 28379 |    27M|   342    (1)| 00:00:05 |
18 |*  1 |  TABLE ACCESS FULL| JACK_TEST | 28379 |    27M|   342    (1)| 00:00:05 |            --这里的Cost消耗比较大,还有Bytes也比较大    
19 -------------------------------------------------------------------------------
20 
21 Predicate Information (identified by operation id):
22 ---------------------------------------------------
23 
24    1 - filter("X">=20000 AND "X"<=40000)
25 
26 Note
27 -----
28    - dynamic sampling used for this statement (level=2)
29 
30 
31 Statistics
32 ----------------------------------------------------------
33       9  recursive calls
34       0  db block gets
35        2576  consistent gets
36       9  physical reads
37       0  redo size
38     1813724  bytes sent via SQL*Net to client
39       15082  bytes received via SQL*Net from client
40        1335  SQL*Net roundtrips to/from client
41       0  sorts (memory)
42       0  sorts (disk)
43       20001  rows processed
44 
45 SQL> analyze table jack_test compute statistics;
46 
47 Table analyzed.
48 
49 Elapsed: 00:00:01.47
50 SQL> select /*+ index(jack_test jack_pks) */ * from jack_test where x between 20000 and 40000;
51 
52 20001 rows selected.
53 
54 Elapsed: 00:00:00.20
55 
56 Execution Plan
57 ----------------------------------------------------------
58 Plan hash value: 674810340
59 
60 -----------------------------------------------------------------------------------------
61 | Id  | Operation            | Name    | Rows    | Bytes | Cost (%CPU)| Time    |
62 -----------------------------------------------------------------------------------------
63 |   0 | SELECT STATEMENT        |        | 20002 |  1543K|   282   (0)| 00:00:04 |
64 |   1 |  TABLE ACCESS BY INDEX ROWID| JACK_TEST | 20002 |  1543K|   282   (0)| 00:00:04 |
65 |*  2 |   INDEX RANGE SCAN        | JACK_PKS    | 20002 |    |    43   (0)| 00:00:01 |
66 -----------------------------------------------------------------------------------------
67 
68 Predicate Information (identified by operation id):
69 ---------------------------------------------------
70 
71    2 - access("X">=20000 AND "X"<=40000)
72 
73 
74 Statistics
75 ----------------------------------------------------------
76       1  recursive calls
77       0  db block gets
78        2899  consistent gets
79       0  physical reads
80       0  redo size
81     1893672  bytes sent via SQL*Net to client
82       15082  bytes received via SQL*Net from client
83        1335  SQL*Net roundtrips to/from client
84       0  sorts (memory)
85       0  sorts (disk)
86       20001  rows processed

小结:

  对于规则表的查询索引访问效率要高于全表扫描。

2.3、比较不规则表用全表扫描与索引访问:

 1 SQL> select /*+ full(echo_test) */ * from echo_test where x between 20000 and 40000;
 2 
 3 20001 rows selected.
 4 
 5 Elapsed: 00:00:00.15
 6 
 7 Execution Plan
 8 ----------------------------------------------------------
 9 Plan hash value: 3930265464
10 
11 -------------------------------------------------------------------------------
12 | Id  | Operation      | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
13 -------------------------------------------------------------------------------
14 |   0 | SELECT STATEMENT  |          | 21652 |    20M|   333    (1)| 00:00:04 |
15 |*  1 |  TABLE ACCESS FULL| ECHO_TEST | 21652 |    20M|   333    (1)| 00:00:04 |
16 -------------------------------------------------------------------------------
17 
18 Predicate Information (identified by operation id):
19 ---------------------------------------------------
20 
21    1 - filter("X">=20000 AND "X"<=40000)
22 
23 Note
24 -----
25    - dynamic sampling used for this statement (level=2)
26 
27 
28 Statistics
29 ----------------------------------------------------------
30     246  recursive calls
31       0  db block gets
32        2630  consistent gets
33       9  physical reads
34       0  redo size
35     1813724  bytes sent via SQL*Net to client
36       15082  bytes received via SQL*Net from client
37        1335  SQL*Net roundtrips to/from client
38       6  sorts (memory)
39       0  sorts (disk)
40       20001  rows processed
41 
42 SQL> select /*+ index(echo_test echo_pk) */ * from echo_test where x between 20000 and 40000;
43 
44 20001 rows selected.
45 
46 Elapsed: 00:00:00.17
47 
48 Execution Plan
49 ----------------------------------------------------------
50 Plan hash value: 2911547479
51 
52 -----------------------------------------------------------------------------------------
53 | Id  | Operation            | Name    | Rows    | Bytes | Cost (%CPU)| Time    |
54 -----------------------------------------------------------------------------------------
55 |   0 | SELECT STATEMENT        |        | 21652 |    20M| 19916   (1)| 00:03:59 |
56 |   1 |  TABLE ACCESS BY INDEX ROWID| ECHO_TEST | 21652 |    20M| 19916   (1)| 00:03:59 |          --这里Cost消耗比较大
57 |*  2 |   INDEX RANGE SCAN        | ECHO_PK    | 21652 |    |    45   (0)| 00:00:01 |          
58 -----------------------------------------------------------------------------------------
59 
60 Predicate Information (identified by operation id):
61 ---------------------------------------------------
62 
63    2 - access("X">=20000 AND "X"<=40000)
64 
65 Note
66 -----
67    - dynamic sampling used for this statement (level=2)
68 
69 
70 Statistics
71 ----------------------------------------------------------
72       7  recursive calls
73       0  db block gets
74       21445  consistent gets                  -- 一致读的数量比较多
75      38  physical reads
76       0  redo size
77     1893672  bytes sent via SQL*Net to client
78       15082  bytes received via SQL*Net from client
79        1335  SQL*Net roundtrips to/from client
80       0  sorts (memory)
81       0  sorts (disk)
82       20001  rows processed

小结:

  对于不规则表的查询全表扫描的效率要高于索引访问。其中索引访问中consistent gets高达21445之多,而Cost达到了2w左右。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值