如何删除Postgres中表的所有索引?

Eri*_*rin 14 postgresql indexing ddl metadata dynamic-sql

我一直有这个问题:我有一个表上需要删除的20个索引才能进行测试.删除表不会丢弃所有这些元数据.

似乎没有通配符drop index ix_table_*或任何有用的命令.你可以编写的psql周围似乎有一些bash循环.
必须有更好的东西!思考?

Erw*_*ter 13

假设您只想删除普通索引:

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$$;
Run Code Online (Sandbox Code Playgroud)

不碰为限制(的实现细节创建的索引UNIQUE,PK,EXCLUDE).
文件:

DEPENDENCY_INTERNAL (i)
Run Code Online (Sandbox Code Playgroud)

依赖对象是作为创建引用对象的一部分创建的,实际上只是其内部实现的一部分.

您可以将其包装在函数中以便重复执行.
有关:


旁白:这是一个误解:

删除表不会丢弃所有这些元数据.

删除表总是级联到表上的所有索引.


Emi*_*ily 7

这就是我从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;
Run Code Online (Sandbox Code Playgroud)

执行:

SELECT drop_all_indexes();
Run Code Online (Sandbox Code Playgroud)

在实际执行“ DROP INDEX xxx”之前,我将使用“-”注释掉“ EXECUTE ...”行,并取消注释“ RAISE INFO”行,并使用“ select func_name();”运行它。并仔细检查,我没有丢掉我不应该丢的东西。

对于我们的应用程序,我们在一个文件app.sql中拥有所有架构语句,包括索引创建。在整个项目投入生产之前,我们要清理所有历史创建的索引,然后使用以下方法重新创建它们:

psql -f /path/to/app.sql
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。


Sah*_*sci 6

下面的查询删除与任何约束(主键、唯一键)无关的所有用户索引

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
Run Code Online (Sandbox Code Playgroud)

您可以使用\gexecpsql的元命令功能来执行语句