web-dev-qa-db-ja.com

Postgresでテーブルのすべてのインデックスを削除するにはどうすればよいですか?

私はこの問題を抱え続けています。テストを行うために削除する必要のあるテーブルに20個のインデックスがあります。テーブルを削除しても、このメタデータのすべてが削除されるわけではありません。

ワイルドカードはないようですdrop index ix_table_*または任意の便利なコマンド。あなたが書くことができるpsqlの周りにいくつかのbashループがあるようです。
もっと良いものがあるに違いない!考え?

15
Erin

プレーンインデックスのみを削除したい場合:

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$$;

制約の実装の詳細として作成されたインデックス(UNIQUEPKEXCLUDE)には触れません。
ドキュメント:

DEPENDENCY_INTERNAL (i)

依存オブジェクトは、参照オブジェクトの作成の一部として作成されたものであり、実際にはその内部実装の一部にすぎません。

これを関数にラップして、繰り返し実行できます。
関連:


余談:これは誤解です:

テーブルを削除しても、このメタデータのすべてが削除されるわけではありません。

テーブルの削除alwaysは、テーブルのすべてのインデックスにカスケードされます。

13

これは、すべてのpkeyを除いて、postgresからすべてのインデックスを削除する方法です。

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();」で実行します。落としてはいけないものを落としていないか再確認してください。

このアプリケーションでは、インデックスの作成を含むすべてのスキーマステートメントが1つのファイルapp.sqlにあります。このプロジェクト全体が本番環境に移行する前に、これまでに作成されたすべてのインデックスをクリーンアップしてから、次を使用してそれらを再作成します。

psql -f /path/to/app.sql

お役に立てれば。

6
Emily

以下のクエリは、すべてのserインデックスを削除しますnotに関連していますconstraint(主キー、一意キー)

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メタコマンド機能を使用してステートメントを実行できます

1
Sahap Asci