Firebird 5中的并发索引创建
目前,在构建索引时,不允许对表数据进行任何修改。这是为了创建正确的索引所必需的,以免遗漏构建期间插入的新键。
并发索引构建算法可以显著缩短需要此类读锁的时间。虽然它不能完全消除对表数据并发修改的阻塞需求,但相比传统的非并发算法,阻塞时间要短得多。这在生产环境中尤其有用,因为长时间阻塞用户活动是不切实际或不可能的。
由于并发负载和额外的复杂性,并发索引创建可能比传统方法耗时更长。
语法
新的可选非保留关键字 CONCURRENTLY 用于指定并发索引创建。
创建新索引
CREATE [UNIQUE] [ASC[ENDING] | DESC[ENDING]] INDEX indexname ON tablename {(col [, col ...]) | COMPUTED BY ()} [WHERE ] [CONCURRENTLY]
激活现有索引
ALTER INDEX indexname {ACTIVE | INACTIVE} [CONCURRENTLY]
注意,CONCURRENTLY 只能与 ACTIVE 一起使用。
唯一性验证
在并发构建索引时,很难甚至不可能检查索引的唯一性。因此,当唯一索引被并发创建(或激活)时,它会立即在系统目录中被标记为 NOT VALIDATED。索引构建完成后,当索引包含表中所有记录的键时,才会验证索引的唯一性。
如果唯一性检查成功,NOT VALIDATED 标记将被清除。
如果唯一性检查失败,索引保持活动状态并标记为 NOT VALIDATED。之后用户可以查找并修复重复项,再次验证唯一性,或者酌情删除索引。
注意,NOT VALIDATED 的唯一索引仍然不允许向表中插入重复数据。
要验证唯一索引,请运行
ALTER INDEX indexname VALIDATE UNIQUE
该语句执行索引扫描以查找重复键并检查相应记录。如果未发现重复项,NOT VALIDATED 标记将被清除,索引视为已验证。否则,NOT VALIDATED 标记将保留,索引可在之后再次验证。
isql 命令 SHOW INDEX 现在会显示 NOT VALIDATED 标记(如果存在)。
表约束
尚不支持为表约束(如 PRIMARY|UNIQUE|FOREIGN KEY)并发创建索引。未来可能支持 PRIMARY|UNIQUE KEY,但不太可能支持 FOREIGN KEY。
示例
准备包含一些数据的表
create table tab ( id int not null, f1 varchar(64));
insert into tab values (1, '1');
insert into tab values (1, '2');commit;
使用 CONCURRENTLY 子句创建索引
create index idx_tab_f1 on tab(f1) concurrently;
在包含重复数据的列上创建唯一索引
create unique index idx_tab_id on tab(id);
它会报错:
Statement failed, SQLSTATE = 23000
attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
使用 CONCURRENTLY 创建相同的唯一索引
create unique index idx_tab_id on tab(id) concurrently;
它会给出警告:
Validation of unique index "IDX_TAB_ID" failed.
-attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
检查索引是否存在:
show index idx_tab_id;
IDX_TAB_ID UNIQUE NOT VALIDATED INDEX ON (ID)
注意 NOT VALIDATED 标记。
验证索引:
alter index idx_tab_id validate unique;
Statement failed, SQLSTATE = 23000
unsuccessful metadata update-Validation of unique index "IDX_TAB_ID" failed.
-attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
修复重复记录并再次验证
update tab set id = 2 where f1 = '2';
commit;
alter index idx_tab_id validate unique;
没有错误。
检查索引状态:
show index idx_tab_id;
IDX_TAB_ID UNIQUE INDEX ON (ID)
立即下载 HQbird 并试用:下载 HQbird