创建、更改、删除索引

  SinoDB数据库的索引组织方式有两种:B+树索引与R树索引。B+ 树是大多数数据库所采用的索引组织方式。R 树索引作为表的辅助访问方法,主要用于查找多维空间数据。本文主要讨论B+ 树索引。

1. B+ 树索引

  B+ 树索引按级别进行组织。最高级别包含指向真实的数据的指针或者地址。其他级包含指向不同级别结点的指针,其中所包含的键小于等于更高级别的键。通过索引访问一行数据时,总是在根结点开始读取,然后沿着低级别读取,最终到包含指向数据的指针。

1.1 索引切分

  当一个新的索引值将被插入到一个已经满了的索引结点时,结点必须切分。B+ 树向根部增长。尝试向已满结点增加键,强迫将其切分为 2 个结点,并促使中间键值移向更高级别结点。如果键值造成的切分比结点中其他的键大,则在切分时就自行放置于该结点中。键向下一个高级别的移动可能也会造成高级别结点的切分。如果该高级结点的满结点是根结点,则也会切分。当根节点切分时,树将继续增加一个级别,形成新的根节点。

1.2 保持索引键值最小

  一个索引键是一个字段值,而索引就是基于该字段所建立的。SinoDB动态服务器索引键的最大值为 390 字节。

  我们要尽量保持索引键值大小为最小,原因有两个:

  • 对于动态服务器,一个结点的大小就是一页的大小。小的键值意味着内存中一个页面上能够存储更多键值,在检索数据时减少读取的I/O操作。

  • 小的键值可以减少 B+ 级别,提高索引读取性能。4 级树索引每行的读取次数比 3 级树多一次。如果要读取100,000行数据,这意味着为获取相同的数据3级树可以少进行 100,000 次读取。

2. 索引类型

SinoDB数据库包含以下索引类型:

① 唯一索引

唯一索引要求索引字段中的一个值只能出现一次。

create unique index ix_orders on orders(orders_num) in idx_dbs;

② 重复索引

重复索引允许索引字段里出现重样的值。

create index ix_items on items(manu_code);

③ 复合索引

  在两个或更多字段上建立的索引是复合索引。复合索引有利于多字段连接,可以增加索引值的唯一性。复合索引最多包含 16个字段 ,最大键大小为 390 字节。

create index order_ix1 on orders (order_num, order_date desc);

  这个复合索引中指定了按order_date 递减顺序(缺省为递增顺序)。

  SinoDB数据库的 B+ 树索引可以调转,所以当在单个字段上创建索引时不必指定 ASC (升序)或 DESC (降序)关键词。然而,在复合索引中为特定字段使用 DESC 关键词很有帮助。例如,如果应用经常查询按订单号和订单日期递减排列的订单信息。以上定义的复合索引就消除了数据库服务器重复排序工作。

④ 聚集索引

create cluster index ix_manufact on manufact(manu_code); —创建聚集索引

alter index index_name to cluster; —更改现有索引为聚集索引

  当创建一个聚集索引或更改已有索引为聚集索引时,动态数据库按索引的顺序复制磁盘上的整个表,然后删除旧的表,所以必须在 dbspace 中有足够的空间来容纳表的副本,这个过程中还要求表的排他读取。

  因为数据是以聚集索引中的顺序被写入的,所以每个表只能有一个聚集索引。

  另外,当插入数据或更新数据时,SinoDB并不维护数据行的聚集索引。因此,聚集索引在相对静态的表中更加高效,在动态变化大的表中则相对低效。

3. online 子句

  ONLINE 子句允许用户在使用表的同时创建索引。没有了 ONLINE 子句,CREATE INDEX 语句会给表加排他锁,这意味着在索引建立期间其他用户不可以使用该表。但是不可以将 CREATE CLUSTER INDEX 语句和 ONLINE 子句一起使用。

create index order_ix1 on orders (order_num, order_date desc) online;

4. 分离索引

  分离索引指索引extent与表extent分开存储。缺省情况下,索引 extent 和数据 extent 在 一个 dbspace 中。也可以指定索引存放在单独的 dbspace 中。

create index customer_ix on customer (zipcode) in cust_ix_dbs;

5. 索引填充因子

  创建索引时可以通过 fillfactor 指定每一页索引填充的百分比。填充因子在索引生命周期中不会一直存在。它只在索引建立的时候起作用。

create index state_code_idx on state(code) fillfactor 80;

  如果CREATE INDEX 未指定,则缺省使用onconfig配置参数 FILLFACTOR 指定的值。如果上面两处都未指定,则缺省值是百分之90。

  如果预测建表后不会再大量插入数据,创建索引时可以设置较高的FILLFACTOR 值。如果预测建表后还要大量插入数据,则使用较低的FILLFACTOR 值,以防止结点立即切分。否则,如果 FILLFACTOR 设定得过低,则索引使用的磁盘空间可能产生不必要的增长。

6. 更改、删除、重命名索引

alter index ix_man_cd to cluster;    —更改索引
rename index ix_cust to new_ix_cust;    —重命名索引
drop index ix_stock;  —删除索引

  更改、删除或重命名系统自己创建的索引(比如系统用于强制执行约束的索引)是不允许的,因为这类索引名称以空格开始。为更改、删除或重命名系统创建的索引,必须首先删除相关约束。

7. sysindexes 系统目录

sysindexes 描述了数据库中的每个索引。

[informix@vm84145 ~]$ dbaccess testdb3 -

Database selected.

> select sysindexes.*
> from sysindexes, systables where
> tabname = "fjta_news"
> and systables.tabid = sysindexes.tabid;

idxname    idx_fjta_news_id
owner      informix
tabid      179
idxtype    D
clustered  
part1      1
part2      0
part3      0
part4      0
part5      0
part6      0
part7      0
part8      0
part9      0
part10     0
part11     0
part12     0
part13     0
part14     0
part15     0
part16     0
levels     2
leaves     114.0000000000
nunique    15819.00000000
clust      7635.000000000

1 row(s) retrieved.

> 

  sysindexes 的每一数据行包含一个索引名称、所有者、 tabid、索引类型、是否聚集错音、以及索引中使用的字段数量。

  sysindexes 表包含域 part1 到 part16,标识了每个索引基于的字段。由于每个索引可以存储 16个字段,所以在复合索引中使用的最大列数量是 16.