Utwórz indeks przestrzenny w PostGIS na całym schemacie

9

Załadowałem wiele plików shapefile przy użyciu SPIT (wtyczka QGIS) do mojej bazy danych PostGIS. Te warstwy nie miały indeksu przestrzennego utworzonego podczas ładowania. Zastanawiam się, czy istnieje sposób utworzenia indeksu przestrzennego dla każdej warstwy w schemacie bez pisania zapytania dla każdej warstwy. Nie jestem dobrym pisarzem skryptów PostGIS, więc każda pomoc byłaby bardzo mile widziana.

Dzięki

Ryan Garnett
źródło

Odpowiedzi:

8

Jeśli chcesz grupowo tworzyć indeksy na kolumnach geometrii, możesz wypróbować tę funkcję plpgsql, którą właśnie podrzuciłem:

CREATE OR REPLACE FUNCTION BatchIndex(sn text, tn text, cn text) RETURNS void AS $$
DECLARE i_exists integer;
DECLARE idxname text;
BEGIN
  idxname := 'idx_' || tn || '_' || cn;
  select into i_exists count(*) from pg_class where relname = idxname;

  IF i_exists = 0 THEN
    EXECUTE 'CREATE INDEX ' ||idxname || ' ON '
      || sn || '.' || tn
      || ' USING GIST(' || cn || ')';
  END IF;
END;
$$ LANGUAGE plpgsql;

Nie próbowałem tego ze złością na mojej bazie danych, ale wydaje się, że to działa.

Aby z niego skorzystać, wystarczy uruchomić następującą SELECTinstrukcję:

select BatchIndex('public', f_table_name, f_geometry_column) from geometry_columns where f_table_schema = 'public';

Aby utworzyć indeksy dla wszystkich kolumn geometrii, możesz użyć tego w następujący sposób:

select BatchIndex(f_table_schema, f_table_name, f_geometry_column) from geometry_columns;

Następnie biegnij, VACUUM ANALYZEaby wszystko uporządkować.

MerseyViking
źródło
Dziękuję bardzo, to wygląda świetnie. Uruchomiłem to, ale wydaje się, że jest problem, pamiętajcie, że może to wynikać z mojego braku umiejętności skryptowych. Ale gdy uruchamiam instrukcje SELECT, pojawia się następujący błąd: BŁĄD: funkcja batchindex (nieznana, zmieniająca się postać, zmieniająca się postać) nie istnieje LINIA 1: wybierz BatchIndex ('public', f_table_name, f_geometry_column) ... Nie jestem pewien jeśli mam coś dodać, aby uzyskać partię, lub jeśli jest to po prostu miejsce na coś innego. Zapytanie CREATE przebiegło bez problemu, ale nie wygenerowano żadnych indeksów.
Ryan Garnett
Hmm ... nie jestem pewien, co się tam dzieje. Fakt, że myśli, że pierwszy parametr, który przekazujesz, jest typu, unknowna nie character varyinguruchamia dzwonki alarmowe, ale nie widzę, gdzie ma problem. Zastanowię się, tymczasem jakiś guru PostgreSQL ma ochotę spróbować? :)
MerseyViking
2

Najlepsza odpowiedź nie zadziała, jeśli masz widoki z geometrią. Zmiana instrukcji „JEŚLI”, aby sprawdzić, czy nie próbujesz budować indeksu w widoku, rozwiązuje ten problem. Jeśli chcesz używać widoków z geometrią, zamień ten wiersz:

IF i_exists = 0

z tym:

IF i_exists = 0 AND tn IN (SELECT table_name, table_type FROM information_schema.tables WHERE table_type = 'BASE TABLE')
Josh Brooks
źródło
1

powiedzmy, że twoja tabela „buduje”, możesz indeksować za pomocą GIST

CREATE INDEX building_gindx ON building USING GIST (geom);

Czy tego szukasz?

Naresh
źródło
Dzięki Naresh, nie szukam sposobu na utworzenie indeksów dla wszystkich tabel w schemacie, w systemie wsadowym.
Ryan Garnett