Indeksy współbieżne (CREATE INDEX CONCURRENTLY)
Tworzyć indeksy bez blokowania zapisów za pomocą CREATE INDEX CONCURRENTLY i odzyskiwać sprawność po przerwanych operacjach tworzenia
Indeksy współbieżne (CREATE INDEX CONCURRENTLY) to bezpłatna lekcja SQL Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej SQL Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Academy zawiera 4 lekcji w sumie.
Problem z CREATE INDEX
Standardowe CREATE INDEX uzyskuje blokadę SHARE — blokuje zapisy, ale nie odczyty, przez cały czas tworzenia indeksu. Na tabeli zawierającej miliard wierszy oznacza to trwającą kilka minut przerwę w zapisach.
CONCURRENTLY: rozwiązanie
CREATE INDEX CONCURRENTLY tworzy indeks bez blokowania zapisów:
CREATE INDEX CONCURRENTLY idx_orders_user_id ON orders(user_id);Jak to działa
Dwa skanowania tabeli:
- Pierwsze przejście: utworzenie indeksu na podstawie bieżących wierszy
- Drugie przejście: uwzględnienie wierszy zmienionych podczas pierwszego przejścia
Dodatkowo następuje krótkie oczekiwanie na wszystkie równoległe transakcje, które rozpoczęły się przed rozpoczęciem tworzenia indeksu.
Nie można uruchomić w transakcji
CONCURRENTLY wykonuje dwa zatwierdzenia — dlatego nie może znajdować się w jawnym bloku BEGIN/COMMIT:
BEGIN;
CREATE INDEX CONCURRENTLY ...; -- ERROR
COMMIT;Wolno, ale bez przestoju
CONCURRENTLY trwa dłużej niż standardowe CREATE INDEX (dwa skanowania i oczekiwanie na blokady). Zaletą jest brak przestoju.
Odzyskiwanie po błędzie
Jeśli CONCURRENTLY zakończy się błędem (zostanie przerwane lub wystąpi błąd systemu), indeks pozostanie w stanie INVALID:
SELECT relname FROM pg_class
WHERE relkind = 'i' AND NOT pg_index.indisvalid;
-- Fix: drop and re-create:
DROP INDEX CONCURRENTLY my_idx;
CREATE INDEX CONCURRENTLY my_idx ON ...;REINDEX CONCURRENTLY
Przebudowa bez blokowania, dostępna od PG 12:
REINDEX INDEX CONCURRENTLY orders_user_id_idx;
REINDEX TABLE CONCURRENTLY orders;DROP INDEX CONCURRENTLY
Ta operacja również nie blokuje:
DROP INDEX CONCURRENTLY old_idx;Indeksy unikatowe
Indeksy UNIQUE można również tworzyć z CONCURRENTLY. Jest to przydatne podczas dodawania ograniczeń UNIQUE bez przestoju:
CREATE UNIQUE INDEX CONCURRENTLY users_email_uidx ON users(email);
ALTER TABLE users ADD CONSTRAINT users_email_unique UNIQUE USING INDEX users_email_uidx;Indeksy kluczy obcych
Standardowy wzorzec podczas dodawania klucza obcego do dużej tabeli:
-- 1. Build the index online:
CREATE INDEX CONCURRENTLY orders_user_id_idx ON orders(user_id);
-- 2. Add the FK with NOT VALID (instant):
ALTER TABLE orders ADD CONSTRAINT orders_user_fk
FOREIGN KEY (user_id) REFERENCES users(id) NOT VALID;
-- 3. Validate in the background:
ALTER TABLE orders VALIDATE CONSTRAINT orders_user_fk;Koszt równoczesnego tworzenia indeksu
Dwa pełne skanowania tabeli oraz dodatkowe operacje pomocnicze. Zużywa to zasoby CPU i IO. Jeśli to możliwe, operację należy uruchamiać w godzinach małego ruchu.
Monitorowanie postępu
PG 12+ udostępnia postęp w pg_stat_progress_create_index:
SELECT phase,
blocks_done, blocks_total,
tuples_done, tuples_total
FROM pg_stat_progress_create_index;Podsumowanie
CONCURRENTLY to przyjazny środowisku produkcyjnemu sposób zarządzania indeksami.
- CREATE/DROP/REINDEX CONCURRENTLY nie blokują zapisów
- Nie można uruchamiać ich w transakcji
- Błędy pozostawiają indeksy INVALID — należy je usunąć
- Postęp można monitorować za pomocą pg_stat_progress_create_index
Szybki test
Dlaczego CREATE INDEX CONCURRENTLY nie może działać wewnątrz jawnego bloku BEGIN/COMMIT?
Często zadawane pytania
Czy lekcja „Indeksy współbieżne (CREATE INDEX CONCURRENTLY)” jest bezpłatna?
Tak — pełny tekst „Indeksy współbieżne (CREATE INDEX CONCURRENTLY)” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu SQL Academy, przejdź na CoddyKit PRO. Kurs SQL Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Indeksy współbieżne (CREATE INDEX CONCURRENTLY)”?
Tworzyć indeksy bez blokowania zapisów za pomocą CREATE INDEX CONCURRENTLY i odzyskiwać sprawność po przerwanych operacjach tworzenia Ćwiczysz SQL Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć SQL Academy?
Nie wymagamy żadnego doświadczenia. SQL Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Indeksy współbieżne (CREATE INDEX CONCURRENTLY)”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji SQL Academy?
Tak. Każda lekcja SQL Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Migracje online: dlaczego ALTER TABLE blokuje
- Indeksy współbieżne (CREATE INDEX CONCURRENTLY)
- Zmiana nazw kolumn bez przestoju
- Narzędzia: Flyway, Liquibase, Sqitch