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.