2015-12-01 43 views
9

Wciąż mam ten problem: Mam 20 indeksów na stole, które muszę upuścić, aby wykonać test. Upuszczenie tabeli nie powoduje utraty wszystkich tych metadanych.Jak mogę usunąć wszystkie indeksy tabeli w PostgreSQL?

Wygląda na to, że nie ma symbolu wieloznacznego drop index ix_table_* ani żadnego użytecznego polecenia. Wygląda na to, że wokół psql są pętle basha, które możesz napisać.
Musi być coś lepszego! Myśli?

+0

http://stackoverflow.com/a/6777904/3961156 –

+0

Kiedy mówisz "wszystkie indeksy", czy chcesz uwzględnić ograniczenia ('UNIQUE',' PK', 'EXCLUDE'), które są implementowane przez utworzenie indentycznie indeksować? –

+0

Nie, tylko indeksy w tym przypadku. – Erin

Odpowiedz

10

Zakładając, że tylko chcesz usunąć zwykły indeksy:

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

nie dotyka indeksy utworzone jako szczegółach wdrożenia ograniczeń (UNIQUE, PK, EXCLUDE).
The documentation:

DEPENDENCY_INTERNAL (i) 

Przedmiotem zależne został stworzony jako część stworzenia odwołuje obiektu, a to tak naprawdę tylko część jego wewnętrznej realizacji.

Można go zawinąć w funkcję do wielokrotnego wykonywania.
pokrewne:


marginesie: To nieporozumienie:

spadnie ze stołu nie spada się z treścią metadanych.

Upuszczenie tabeli zawsze kaskady do wszystkich indeksów na stole.

+0

Czy masz jakieś pomysły, dlaczego upuszczenie tabeli nie spadnie na indeksy? Ponieważ tak nie jest. Tabele i indeksy zostały wygenerowane przeze mnie bawiąc się klasami alchemii sql i klasami mixin - coś, co jest dla mnie wciąż czarną skrzynką. – Erin

+0

@Erin: Czy na pewno nie ma drugiej tabeli o tej samej nazwie w innym schemacie? –

+0

Trochę czasu zajęło zrozumienie, że dane wejściowe do tego zapytania brzmią ''tbl'' –

2

W ten sposób usuwam wszystkie indeksy z PostgreSQL, wyłączając wszystkie 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; 

Aby wykonać:

SELECT drop_all_indexes(); 

Przed faktycznie wykonujące 'DROP INDEX xxx', chciałbym wypowiedzieć się wiersz 'EXECUTE ...' przy użyciu '-', i odkomentować „RAISE INFO "wiersz, uruchom go za pomocą" wybierz func_name(); " i sprawdź dwukrotnie Nie upuszczam czegoś, czego nie powinienem.

Dla naszej aplikacji mamy wszystkie instrukcje schematów, w tym tworzenie indeksów w jednym pliku app.sql. Przed tym cały projekt trafia do produkcji, chcemy, aby oczyścić wszystkie historycznie utworzone indeksy, a następnie odtworzyć je za pomocą:

psql -f /path/to/app.sql 

Nadzieja to pomaga.