web-dev-qa-db-fra.com

Comment supprimer tous les index d'une table dans Postgres?

Je continue d'avoir ce problème: j'ai comme 20 index sur une table que je dois supprimer pour faire des tests. Supprimer la table ne supprime pas toutes ces métadonnées.

Il ne semble pas y avoir de caractère générique drop index ix_table_* ou toute commande utile. Il semble y avoir des boucles bash autour de psql que vous pouvez écrire.
Il doit y avoir quelque chose de mieux! Pensées?

15
Erin

En supposant que vous ne souhaitiez supprimer que des index simples:

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

Ne touche pas aux index créés comme détail d'implémentation des contraintes (UNIQUE, PK, EXCLUDE).
La documentation:

DEPENDENCY_INTERNAL (i)

L'objet dépendant a été créé dans le cadre de la création de l'objet référencé et n'est vraiment qu'une partie de son implémentation interne.

Vous pouvez envelopper cela dans une fonction pour une exécution répétée.
En relation:


A part: C'est un malentendu:

Supprimer la table ne supprime pas toutes ces métadonnées.

Suppression d'une table toujours en cascade vers tous les index de la table.

13
Erwin Brandstetter

C'est ainsi que je supprime tous les index des postgres, à l'exclusion de tous les 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;

Éxécuter:

SELECT drop_all_indexes();

Avant d'exécuter réellement 'DROP INDEX xxx', je commenterais la ligne 'EXECUTE ...' en utilisant '-', et décommenterais la ligne 'RAISE INFO', l'exécuter avec 'select func_name ();' et revérifiez que je ne laisse pas tomber quelque chose que je ne devrais pas.

Pour notre application, nous avons toutes les instructions de schéma, y ​​compris la création d'index dans un fichier app.sql. Avant que tout ce projet ne soit mis en production, nous voulons nettoyer tous les index créés historiquement, puis les recréer en utilisant:

psql -f /path/to/app.sql

J'espère que cela t'aides.

6
Emily

La requête ci-dessous supprime tous les index tilisateur qui sont pas liés à n'importe quel contrainte (clé primaire, clé unique)

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

Vous pouvez utiliser \gexec fonction méta-commande de psql pour exécuter l'instruction

1
Sahap Asci