Amazon Aurora DSQL 作为预览服务提供。要了解更多信息,请参阅《AWS Service Terms》中的 Betas and Previews
Aurora DSQL 中的异步索引
CREATE INDEX ASYNC
命令在指定表的某列上创建索引。CREATE INDEX ASYNC
是一个异步 DDL 操作,因此,此命令不会阻止其它事务。
当您运行此命令时,Aurora DSQL 会立即返回 job_id
。您可以随时通过 sys.jobs
系统视图查看异步作业的状态。
当索引创建作业正在进行时,您可以使用以下过程和命令:
sys.wait_for_job(job_id)
-
阻止该会话,直到指定的作业完成或失败。此过程返回布尔值。
DROP INDEX
-
取消正在进行的索引构建作业。
当 Aurora DSQL 完成异步索引任务时,它会更新系统目录以显示该索引处于活动状态。如果此时其它事务引用同一命名空间中的对象,则您可能会看到并发错误。
语法
CREATE INDEX ASYNC
使用下面的语法。
CREATE [ UNIQUE ] INDEX ASYNC [ IF NOT EXISTS ] name ON table_name ( { column_name } [ NULLS { FIRST | LAST } ] ) [ INCLUDE ( column_name [, ...] ) ] [ NULLS [ NOT ] DISTINCT ]
参数
UNIQUE
-
指示 Aurora DSQL 在它创建索引时和您每次添加数据时,检查表中是否存在重复值。如果指定此参数,则会导致重复条目的插入和更新操作会生成错误。
IF NOT EXISTS
-
指示如果已存在同名的索引,则 Aurora DSQL 不应引发异常。在这种情况下,Aurora DSQL 不会创建新索引。请注意,您尝试创建的索引的结构可能与现有的索引截然不同。如果您指定此参数,则需要索引名称。
name
-
索引的名称。您不能在此参数中包含架构的名称。
Aurora DSQL 在与其父表相同的架构中创建索引。索引的名称必须与架构中任何其它对象(例如表或索引)的名称不同。
如果您未指定名称,Aurora DSQL 将根据父表和索引列的名称自动生成名称。例如,如果您运行
CREATE INDEX ASYNC on table1 (col1, col2)
,Aurora DSQL 会自动将索引命名为table1_col1_col2_idx
。 NULLS FIRST | LAST
-
空列和非空列的排序顺序。
FIRST
表示 Aurora DSQL 应先对空列进行排序,然后再对非空列进行排序。LAST
表示 Aurora DSQL 应先对非空列进行排序,之后再对空列进行排序。 INCLUDE
-
要作为非键列包含在索引中的列的列表。您不能在索引扫描搜索限定条件中使用非键列。就索引的唯一性而言,Aurora DSQL 会忽略该列。
NULLS DISTINCT | NULLS NOT DISTINCT
-
指定 Aurora DSQL 是否应将空值视为唯一索引中的不同值。默认值为
DISTINCT
,这意味着唯一索引可以在一列中包含多个空值。NOT DISTINCT
表示索引不能在一列中包含多个空值。
使用说明
请考虑以下准则:
-
CREATE INDEX ASYNC
命令不引入锁。它也不会影响 Aurora DSQL 用来创建索引的基表。 -
在架构迁移操作期间,
sys.wait_for_job(job_id)
过程很有用。它可确保后续的 DDL 和 DML 操作以新创建的索引为目标。 -
每当 Aurora DSQL 运行新的异步任务时,它都会检查
sys.jobs
视图,并删除状态为completed
或failed
超过 30 分钟的任务。这样,sys.jobs
主要显示正在进行的任务,而不包含有关旧任务的信息。 -
如果 Aurora DSQL 无法构建异步索引,则索引将保持
INVALID
。对于唯一索引,DML 操作受唯一性约束所制约,直至您删除索引。我们建议您删除无效的索引并重新创建它们。
创建索引:示例
以下示例演示如何创建架构、表和索引。
-
创建名为
test.departments
的文件。CREATE SCHEMA test; CREATE TABLE test.departments (name varchar(255) primary key not null, manager varchar(255), size varchar(4));
-
在表中插入一行。
INSERT INTO test.departments VALUES ('Human Resources', 'John Doe', '10')
-
创建异步索引。
CREATE INDEX ASYNC test_index on test.departments(name, manager, size);
CREATE INDEX
命令返回作业 ID,如下所示。job_id -------------------------- jh2gbtx4mzhgfkbimtgwn5j45y
job_id
表示 Aurora DSQL 已经提交了新作业来创建索引。可以使用过程sys.wait_for_job(job_id)
来阻止会话中的其它工作,直到作业完成或超时。
查询索引创建的状态:示例
查询 sys.jobs
系统视图以查看索引的创建状态,如以下示例所示。
SELECT * FROM sys.jobs
Aurora DSQL 返回与下面类似的响应。
job_id | status | details ----------------------------+------------+--------- vs3kcl3rt5ddpk3a6xcq57cmcy | completed | ihbyw2aoirfnrdfoc4ojnlamoq | processing |
状态列可以是以下值之一:
submitted
-
任务已提交,但是 Aurora DSQL 尚未开始处理该任务。
processing
-
Aurora DSQL 正在处理该任务。
failed
-
任务失败。有关更多信息,请参阅详细信息列。如果 Aurora DSQL 未能构建索引,Aurora DSQL 不会自动移除索引定义。您必须使用
DROP INDEX
命令手动移除索引。 completed
-
Aurora DSQL
也可以通过目录表 pg_index
和 pg_class
查询索引的状态。具体而言,属性 indisvalid
和 indisimmediate
可以告诉您索引处于什么状态。当 Aurora DSQL 创建索引时,索引的初始状态为 INVALID
。索引的 indisvalid
标志返回 FALSE
或 f
,表示该索引无效。如果标志返回 TRUE
或 t
,则索引已就绪。
select relname as index_name, indisvalid as is_valid, pg_get_indexdef(indexrelid) as index_definition from pg_index, pg_class where pg_class.oid = indexrelid and indrelid = 'test.departments'::regclass;
index_name | is_valid | index_definition ------------------+----------+------------------------------------------------------------------------------------------------------------------- department_pkey | t | CREATE UNIQUE INDEX department_pkey ON test.departments USING btree_index (title) INCLUDE (name, manager, size) test_index1 | t | CREATE INDEX test_index1 ON test.departments USING btree_index (name, manager, size)
查询索引的状态:示例
可以使用目录表 pg_index
和 pg_class
查询索引的状态。具体来说,属性 indisvalid
和 indisimmediate
告诉您索引的状态。以下示例显示了示例查询和结果。
SELECT relname AS index_name, indisvalid AS is_valid, pg_get_indexdef(indexrelid) AS index_definition FROM pg_index, pg_class WHERE pg_class.oid = indexrelid AND indrelid = 'test.departments'::regclass; index_name | is_valid | index_definition ------------------+----------+------------------------------------------------------------------------------------------------------------------- department_pkey | t | CREATE UNIQUE INDEX department_pkey ON test.departments USING btree_index (title) INCLUDE (name, manager, size) test_index1 | t | CREATE INDEX test_index1 ON test.departments USING btree_index (name, manager, size)
当 Aurora DSQL 创建索引时,索引的初始状态为 INVALID
。索引的 indisvalid
列显示 FALSE
或 f
,表示该索引无效。如果该列显示 TRUE
或 t
,则索引已就绪。
indisunique
标志指示索引为 UNIQUE
。要了解表是否要接受并发写入的唯一性检查,请查询 pg_index
中的 indimmediate
列,如下面的查询所示。
SELECT relname AS index_name, indimmediate AS check_unique, pg_get_indexdef(indexrelid) AS index_definition FROM pg_index, pg_class WHERE pg_class.oid = indexrelid AND indrelid = 'test.departments'::regclass; index_name | check_unique | index_definition ------------------+----------+------------------------------------------------------------------------------------------------------------------- department_pkey | t | CREATE UNIQUE INDEX department_pkey ON test.departments USING btree_index (title) INCLUDE (name, manager, size) test_index1 | f | CREATE INDEX test_index1 ON test.departments USING btree_index (name, manager, size)
如果该列显示 f
并且您的作业处于状态 processing
,则索引仍在创建中。对索引的写入不受唯一性检查的约束。如果列显示 t
且作业状态为 processing
,则已构建初始索引,但尚未对索引中的所有行执行唯一性检查。但是,对于当前和将来对索引的所有写入,Aurora DSQL 将执行唯一性检查。