2013-09-02 16 views
27

Czy tworzenie indeksu jest skuteczniejsze po zakończeniu ładowania danych lub przed, czy też nie ma znaczenia?Najbardziej efektywny sposób tworzenia indeksu w Postgresie

Załóżmy na przykład, że mam 500 plików do załadowania do bazy danych Postgres 8.4 DB. Oto dwa scenariusze tworzenia indeksów, których mogłem użyć:

  1. Utwórz indeks po utworzeniu tabeli, a następnie wczytaj każdy plik do tabeli; lub
  2. Utwórz indeks po wczytaniu wszystkich plików do tabeli.

Dane samej tabeli mają około 45 gigabajtów. Indeks ma około 12 gigabajtów. Używam standardowego indeksu. Został utworzony w następujący sposób:

CREATE INDEX idx_name ON table_name (column_name); 

Ładowanie danych używa COPY FROM.

Po wczytaniu wszystkich plików, żadne uaktualnienia, usunięcia ani dodatkowe obciążenia nie będą występować w tabeli (jest to dzienna wartość danych, która nie ulegnie zmianie). Więc chciałem zapytać, który scenariusz byłby najbardziej wydajny? Wstępne testy wydają się wskazywać, że ładowanie wszystkich plików, a następnie tworzenie indeksu (scenariusz 2) jest szybsze, ale nie dokonałem żadnego naukowego porównania tych dwóch podejść.

Odpowiedz

43

Twoja obserwacja jest poprawna - znacznie wydajniejsze jest najpierw ładowanie danych, a dopiero potem tworzenie indeksu. Powodem tego jest to, że aktualizacje indeksu podczas wstawiania są drogie. Jeśli utworzysz indeks po wszystkich danych, jest on znacznie szybszy.

To idzie jeszcze dalej - jeśli chcesz zaimportować dużą ilość danych do istniejącej tabeli indeksowanej, często lepiej jest najpierw usunąć istniejący indeks, zaimportować dane, a następnie ponownie utworzyć indeks.

Jedną z wad tworzenia indeksu po zaimportowaniu jest to, że tabela musi być zablokowana, a to może zająć dużo czasu (nie zostanie zablokowane w przeciwnym scenariuszu). Jednak w PostgreSQL 8.2 i nowszych wersjach można użyć CREATE INDEX CONCURRENTLY, która nie blokuje tabeli podczas indeksowania (z pewnymi zastrzeżeniami).

+0

Cóż, gdy stół jest zablokowany, nikt nie może czytać ani pisać, co może być bardzo denerwujące, nawet w nocy. Lepiej używać CREATE INDEX CONCURRENTLY – mvp

+0

@BradTilley: Myślałem, że to nowa funkcja, ale PostgreSQL 8.4 [obsługuje ją] (http://www.postgresql.org/docs/8.4/static/sql-createindex.html). – mvp

+4

"* gdy stół jest zablokowany, nikt nie może czytać ani pisać *" - Nie sądzę, że to prawda. Kiedy uruchomiony jest "CREATE INDEX", tablica nadal może być czytana, ale nie aktualizowana, jeśli się nie mylę. –

Powiązane problemy