我一直有这个问题:我有一个表上需要删除的20个索引才能进行测试。删除表格并不会丢弃所有这些元数据。
似乎不是通配符drop index ix_table_*
或任何有用的命令。你可以编写一些围绕psql的bash循环
必须有更好的东西!想法?
答案 0 :(得分:12)
假设您只想删除普通索引:
DO
$$BEGIN
EXECUTE (
SELECT 'DROP INDEX ' || string_agg(indexrelid::regclass::text, ', ')
FROM pg_index i
LEFT JOIN pg_depend d ON d.objid = i.indexrelid
AND d.deptype = 'i'
WHERE i.indrelid = 'your_table_name_here'::regclass -- possibly schema-qualified
AND d.objid IS NULL -- no internal dependency
);
END$$;
不接触作为约束的实施细节创建的索引(UNIQUE
,PK
,EXCLUDE
)。
The documentation:
DEPENDENCY_INTERNAL (i)
依赖对象是作为创建引用的一部分创建的 对象,实际上只是其内部实现的一部分。
你可以将它包装在一个重复执行的函数中 相关:
除此之外:这是一个误解:
删除表格并不会丢弃所有这些元数据。
删除表始终级联到表中的所有索引。
答案 1 :(得分:5)
这是我从postgres删除所有索引的方法,不包括所有pkey。
CREATE OR REPLACE FUNCTION drop_all_indexes() RETURNS INTEGER AS $$
DECLARE
i RECORD;
BEGIN
FOR i IN
(SELECT relname FROM pg_class
-- exclude all pkey, exclude system catalog which starts with 'pg_'
WHERE relkind = 'i' AND relname NOT LIKE '%_pkey%' AND relname NOT LIKE 'pg_%')
LOOP
-- RAISE INFO 'DROPING INDEX: %', i.relname;
EXECUTE 'DROP INDEX ' || i.relname;
END LOOP;
RETURN 1;
END;
$$ LANGUAGE plpgsql;
执行:
SELECT drop_all_indexes();
在实际执行'DROP INDEX xxx'之前,我会使用' - '注释'EXECUTE ...'行,并取消注释'RAISE INFO'行,用'select func_name();'运行它并仔细检查我不会丢弃我不应该丢弃的东西。
对于我们的应用程序,我们有所有模式语句,包括在一个文件 app.sql 中创建索引。在整个项目投入生产之前,我们希望清理所有历史创建的索引,然后使用以下命令重新创建它们:
psql -f /path/to/app.sql
希望这有帮助。
答案 2 :(得分:1)
下面的查询会删除与任何约束(主键,唯一键)无关不相关的所有用户索引
SELECT
format('DROP INDEX %I.%I;', n.nspname, c_ind.relname)
FROM pg_index ind
JOIN pg_class c_ind ON c_ind.oid = ind.indexrelid
JOIN pg_namespace n ON n.oid = c_ind.relnamespace
LEFT JOIN pg_constraint cons ON cons.conindid = ind.indexrelid
WHERE
n.nspname NOT IN ('pg_catalog','information_schema') AND
n.nspname !~ '^pg_toast'::TEXT AND
cons.oid IS NULL
您可以使用psql的\gexec
元命令功能来执行语句