本节描述如何创建索引。要在用户自己的模式中创建索引,至少要满足如下条件之一:
- 要被索引的表是在自己的模式中 ;
- 在要被索引的表上有 CREATE INDEX 权限;
- 具有 CREATE ANY INDEX 数据库权限。
要在其他模式中创建索引,用户必须具有 CREATE ANY INDEX 数据库权限。
- 显式地创建索引
可以用 CREATE INDEX 语句显式地创建索引。
例 在 emp 表的 ename 列上创建一个名为 emp_ename 的索引,该索引使用表空间 users
CREATE INDEX emp_ename ON emp(ename) STORAGE ( INITIAL 50, NEXT 50, ON USERS);
复制
上述语句为该索引显式地指定了几个存储设置和一个表空间。如果没有给索引指定存储选项,则 INITIAL 和 NEXT 等存储选项会自动使用表空间的默认存储选项。
下面介绍几种常见索引的显式创建方法。
1.1 创建聚集索引
DM8 中表(列存储表和堆表除外)都是使用 B 树索引结构管理的,每一个普通表都有且仅有一个聚集索引,数据都通过聚集索引键排序,根据聚集索引键可以快速查询任何记录。
当建表语句未指定聚集索引键时,DM8 的默认聚集索引键是 ROWID。若指定索引键,表中数据都会根据指定索引键排序。
建表后,DM8 也可以用创建新聚集索引的方式来重建表数据,并按新的聚集索引排序。
例 可以对 emp 表以 ename 列新建聚集索引
CREATE CLUSTER INDEX clu_emp_name ON emp(ename);
复制
新建聚集索引会重建这个表以及其所有索引,包括二级索引、函数索引,是一个代价非常大的操作。因此,最好在建表时就确定聚集索引键,或在表中数据比较少时新建聚集索引,而尽量不要对数据量非常大的表建立聚集索引。
创建聚集索引的约束条件:
- 每张表中只允许有一个聚集索引,如果之前已经指定过 CLUSTER INDEX 或者指定了 CLUSTER PK,则用户新建立 CLUSTER INDEX 时系统会自动删除原先的聚集索引。但如果新建聚集索引时指定的创建方式(列,顺序)和之前的聚集索引一样,则会报错;
- 指定 CLUSTER INDEX 操作需要重建表上的所有索引,包括 PK 索引;
- 删除聚集索引时,缺省以 ROWID 排序,自动重建所有索引;
- 若聚集索引是默认的 ROWID 索引,不允许删除;
- 聚集索引不能应用到函数索引中;
- 不能在列存储表上新建/删除聚集索引;
- 建聚集索引语句不能含有 partition_clause 子句;
- 在临时表上增删索引会使当前会话上临时 b 树数据丢失。
1.2 创建唯一索引
索引可以是唯一的或非唯一的。唯一索引可以保证表上不会有两行数据在键列上具有相同的值,非唯一索引不会在键列上施加这个限制。
可用 CREATE UNIQUE INDEX 语句来创建唯一索引。
例 创建一个唯一索引
CREATE UNIQUE INDEX dept_unique_index ON dept (dname) STORAGE (ON users);
复制
用户可以在希望的列上定义 UNIQUE 完整性约束,DM8 通过自动地在唯一键上定义一个唯一索引来保证 UNIQUE 完整性约束。
1.3 创建基于函数的索引
基于函数的索引促进了限定函数或表达式的返回值的查询,该函数或表达式的值被预先计算出来并存储在索引中。正确使用函数索引,可以带来以下好处:
- 创建更强有力的分类,例如可以用 UPPER 和 LOWER 函数执行区分大小写的分类;
- 预先计算出计算密集的函数的值,并在索引中将其分类。可以在索引中存储要经常访问的计算密集的函数,当需要访问值时,该值已经计算出来了。因此,极大地改善了查询的执行性能;
- 增加了优化器执行范围扫描而不是全表扫描的情况的数量。
例 考虑如下 WHERE 子句中的表达式
CREATE INDEX idx ON example_tab(column_a + column_b); SELECT * FROM example_tab WHERE column_a + column_b < 10;
复制
因为该索引是建立在 column_a + column_b 之上的,所以优化器可以为该查询使用范围扫描。优化器根据该索引计算查询代价,如果代价最少,优化器就会选择该函数索引,column_a + column_b 就不会重复计算。
创建函数索引有以下约束条件:
- 表达式可以由多列组成,不同的列不能超过 63 个;
- 表达式不允许为时间间隔类型;
- 表达式中不允许出现半透明加密列;
- 函数索引表达式的长度理论值不能超过 816 个字符(包括生成后的指令和字符串);
- 函数索引不能为 CLUSTER 或 PRIMARY KEY 类型;
- 表达式不支持集函数和不确定函数,不确定函数为每次执行得到的结果不确定,系统中不确定函数包括:RAND、SOUNDEX、CURDATE、CURTIME、CURRENT_DATE、CURRENT_TIME、CURRENT_TIMESTAMP、GETDATE、NOW、SYSDATE、CUR_DATABASE、DBID、EXTENT、PAGE、SESSID、UID、USER、VSIZE、SET_TABLE_OPTION、SET_INDEX_OPTION、UNLOCK_LOGIN、CHECK_LOGIN、GET_AUDIT、CFALGORITHMSENCRYPT、SF_MAC_LABEL_TO_CHAR、CFALGORITHMSDECRYPT、BFALGORITHMSENCRYPT、SF_MAC_LABEL_FROM_CHAR、BFALGORITHMSDECRYPT、SF_MAC_LABEL_CMP;
- 快速装载不支持含有函数索引的表;
- 若函数索引中要使用用户自定义的函数,则函数必须是指定了 DETERMINISTIC 属性的确定性函数;
- 若函数索引中使用的确定性函数发生了变更或删除,用户需手动重建函数索引;
- 若函数索引中使用的确定性函数内有不确定因素,会导致前后计算结果不同的情况。在查询使用函数索引时,使用数据插入函数索引时的计算结果为 KEY 值;修改时可能会导致在使用函数索引过程中出现根据聚集索引无法在函数索引中找到相应记录的情况,对此进行报错处理;
- 临时表不支持函数索引。