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?
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.
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.
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