predicate 列存储索引扫描_17.读书笔记收获不止Oracle之 索引存储列值

17.读书笔记收获不止Oracle之 索引存储列值

下面来看下索引的第二个特点,索引存储列值及rowid的特性。

1.  简单示例

SQL>create table t as select * from dba_objects;

Create index idx1_object_id on t (object_id);

Select count(*) from t;

COUNT(*)

----------

91717

表的情况和索引的情况的差别在于表把整行的记录依次放进BLOCK形成DATA的BLOCK,而索引是把所在列的记录排序后依次放进BLOCK里面形成INDEX_BLOCK。在没有索引的情况下,DATA BLOCK中可以统计出表记录数,INDEX BLOCK也可以的。

不过INDEX BLOCK里存放的值是表特定的索引列,容纳空间要比存放整行也就是所有列的DATA BLOCK要少得多。用索引一定会高效。

2.  简单示例二

SQL>set autotrace on

SQL> set linesize 1000

Set timing on

Select count(*) from t;

COUNT(*)

----------

91717

Elapsed: 00:00:00.26

Execution Plan

----------------------------------------------------------

Plan hash value: 2966233522

-------------------------------------------------------------------

| Id | Operation         | Name | Rows  | Cost (%CPU)| Time             |

-------------------------------------------------------------------

|   0| SELECT STATEMENT   |        |   1 |  429   (1)| 00:00:01 |

|   1|  SORT AGGREGATE    |     |   1 |           |  |

|   2|   TABLE ACCESS FULL| T       | 91717 |   429  (1)| 00:00:01 |

-------------------------------------------------------------------

Statistics

----------------------------------------------------------

33 recursive calls

0  dbblock gets

1564  consistent gets

1539  physical reads

0  redosize

544  bytes sent via SQL*Net to client

551  bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

3 sorts (memory)

0 sorts (disk)

1  rowsprocessed

发现还是使用了全表扫描,这是因为索引列有空的记录,不能准确统计表记录数。

继续查找:

SQL> select count(*) from t where object_id is not null;

COUNT(*)

----------

91717

Elapsed: 00:00:00.05

Execution Plan

----------------------------------------------------------

Plan hash value: 1296839119

----------------------------------------------------------------------------------------

| Id | Operation            | Name        | Rows | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------------

|   0| SELECT STATEMENT      |              |    1 |     5 |    57  (0)| 00:00:01 |

|   1|  SORT AGGREGATE       |            |    1 |     5 |          |               |

|*  2|   INDEX FAST FULL SCAN| IDX1_OBJECT_ID| 91717 |   447K|    57     (0)| 00:00:01 |

----------------------------------------------------------------------------------------

Predicate Information (identified byoperation id):

---------------------------------------------------

2- filter("OBJECT_ID" IS NOT NULL)

Statistics

----------------------------------------------------------

1 recursive calls

0  dbblock gets

211  consistent gets

203  physical reads

0  redosize

544  bytes sent via SQL*Net to client

551  bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1  rowsprocessed

将此列为非空后,走的是索引。

也可以修改OBJECT_ID列的属性,修改为不允许为空

SQL> alter table t modify object_id not null;

继续查询:

select count(*) from t ;

COUNT(*)

----------

91717

Elapsed: 00:00:00.01

Execution Plan

----------------------------------------------------------

Plan hash value: 1296839119

--------------------------------------------------------------------------------

| Id | Operation            | Name        | Rows | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------

|   0| SELECT STATEMENT      |              |    1 |    57          (0)| 00:00:01 |

|   1|  SORT AGGREGATE       |            |    1 |        |                |

|   2|   INDEX FAST FULL SCAN| IDX1_OBJECT_ID | 91717|    57    (0)| 00:00:01 |

--------------------------------------------------------------------------------

Statistics

----------------------------------------------------------

8 recursive calls

0  dbblock gets

224  consistent gets

0 physical reads

0  redosize

544  bytes sent via SQL*Net to client

551  bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

2 sorts (memory)

0 sorts (disk)

1  rowsprocessed

也是走索引了。

此外还可以修改该列为主键也可以同样实现走索引。

3.  简单示例三

SQL> drop table t purge;

SQL> alter table t add constraintpk1_object_id primary key (OBJECT_ID);

SQL> set autotrace on

SQL> set linesize 1000

SQL> set timing on

SQL> select count(*) from t;

COUNT(*)

----------

91717

Elapsed: 00:00:00.06

Execution Plan

----------------------------------------------------------

Plan hash value: 1604907147

-------------------------------------------------------------------------------

| Id | Operation            | Name       | Rows | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------

|   0| SELECT STATEMENT      |             |    1 |    53  (0)| 00:00:01 |

|   1|  SORT AGGREGATE       |           |    1 |        |                 |

|   2|   INDEX FAST FULL SCAN| PK1_OBJECT_ID | 91717|    53      (0)|00:00:01 |

-------------------------------------------------------------------------------

Statistics

----------------------------------------------------------

12 recursive calls

0  dbblock gets

213  consistent gets

191  physical reads

0  redosize

544  bytes sent via SQL*Net to client

551  bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

2 sorts (memory)

0 sorts (disk)

1  rowsprocessed

在主键上建的索引,然后在使用count(*)之后也是使用走索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值