我正在开发一个函数,该函数可以添加不存在的索引。我遇到了无法获取要比较的索引列表的问题。有什么想法吗?
这与使用以下代码解决的列创建问题类似:https :
//stackoverflow.com/a/12603892/368511
我正在开发一个函数,该函数可以添加不存在的索引。我遇到了无法获取要比较的索引列表的问题。有什么想法吗?
这与使用以下代码解决的列创建问题类似:https :
//stackoverflow.com/a/12603892/368511
Answers:
如果您不关心索引的名称,请让Postgres自动为其命名:
CREATE INDEX ON tbl1 (col1);
(几乎)与:
CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
除了Postgres会避免命名冲突并自动选择下一个免费名称:
tbl1_col1_idx
tbl1_col1_idx2
tbl1_col1_idx3
...
去尝试一下。但是,很明显,你会不会想创建多个冗余索引。因此,盲目创建一个新的想法不是一个好主意。
一种非常简单的测试方法是将模式限定的名称强制转换为regclass
:
SELECT 'myschema.myname'::regclass;
如果抛出异常,则名称是免费的。
或者,为了在不引发异常的情况下进行测试,请在DO
语句中使用:
DO
$$
BEGIN
IF NOT EXISTS (
SELECT
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'mytable_mycolumn_idx'
AND n.nspname = 'myschema'
) THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
这不适用于CREATE INDEX CONCURRENTLY
,因为该变体不能包装在外部事务中。请参阅下面@Gregory的评论。
该DO
声明是在Postgres 9.0中引入的。在早期版本中,您必须创建一个函数来执行相同的操作。
有关详细信息,请pg_class
参见手册。手册中
有关索引的基础。
您可以使用新功能to_regclass()
进行检查而不会引发异常:
DO
$$
BEGIN
IF to_regclass('myschema.mytable_mycolumn_idx') IS NULL THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
如果该名称的索引(或另一个对象)不存在,则返回NULL。看到:
现在可用:
CREATE INDEX IF NOT EXISTS ...
这也适用CREATE INDEX CONCURRENTLY IF NOT EXISTS
。
但是,手册警告:
请注意,不能保证现有索引类似于将要创建的索引。
这是对对象名称的简单检查。适用于此处的所有变体。
CONCURRENTLY
这种方式添加索引。你会得到ERROR: CREATE INDEX CONCURRENTLY cannot be executed from a function or multi-command string
。