Seq Scan a Index Scan i Index-Only
Dlaczego planer wybiera każdą z tych metod i co mówi to o zapytaniu.
Seq Scan a Index Scan i Index-Only to bezpłatna lekcja SQL Interview Prep 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 Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Interview Prep zawiera 4 lekcji w sumie.
Trzy sposoby odczytywania tabeli
Gdy planista potrzebuje wierszy z tabeli, wybiera jedną z trzech metod dostępu, a rekruterzy oczekują wymienienia wszystkich trzech:
- Seq Scan — odczyt każdego wiersza tabeli od początku do końca.
- Index Scan — przejście po indeksie w celu znalezienia pasujących wierszy, a następnie pobranie każdego z nich z tabeli.
- Index-Only Scan — udzielenie odpowiedzi wyłącznie na podstawie indeksu, bez odwoływania się do tabeli.
Zrozumienie, dlaczego planista wybiera każdą z tych metod, jest sednem tej lekcji i gwarantowanym pytaniem dla doświadczonych kandydatów.
Jak działa skanowanie sekwencyjne
Seq Scan odczytuje strony tabeli jedna po drugiej i stosuje ewentualny filtr do każdego wiersza. Indeks nie jest używany.
Może to brzmieć źle, ale często jest to właściwy wybór. Odczyty sekwencyjne są szybkie dla dysku (nie wymagają losowych przeskoków), więc gdy zapytanie zwraca dużą część tabeli, odczytanie wszystkiego jest lepsze niż przeskakiwanie przez indeks miliony razy.
Przykład: skanowanie orders i zachowanie wierszy, dla których amount > 100. Jeśli większość zamówień przekracza 100, skanowanie sekwencyjne jest właściwym wyborem.
EXPLAIN SELECT * FROM orders WHERE amount > 100;
Seq Scan on orders (cost=0.00..18334.00 rows=900000 width=64)
Filter: (amount > 100)Jak działa skanowanie za pomocą indeksu
Index Scan wykorzystuje strukturę B-tree, aby przejść bezpośrednio do pasujących kluczy, a następnie odczytuje odpowiadające im wiersze ze sterty tabeli.
Ta metoda sprawdza się szczególnie dobrze, gdy filtr jest selektywny i zwraca niewielką część tabeli. Wyszukanie 5 wierszy za pomocą indeksu jest lepsze niż odczytanie 10 milionów.
Plan podaje nazwę użytego indeksu. Każde dopasowanie kosztuje jedno wyszukanie w indeksie oraz jeden odczyt ze sterty (odczyt losowy), dlatego skanowanie za pomocą indeksu traci przewagę, gdy zwraca zbyt wiele wierszy.
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
Index Scan using idx_orders_customer on orders
(cost=0.42..38.50 rows=12 width=64)
Index Cond: (customer_id = 42)Selektywność decyduje o wyborze
Pojedynczym pojęciem, które wpływa na wszystkie te decyzje, jest selektywność: ułamek wierszy zachowywanych przez predykat.
- Wysoka selektywność (pasuje niewiele wierszy, na przykład dla unikalnego identyfikatora) sprzyja użyciu Index Scan.
- Niska selektywność (pasuje wiele wierszy, na przykład dla
status IS NOT NULL) sprzyja użyciu Seq Scan.
Przybliżona zasada mówi, że gdy zapytanie zwraca więcej niż około 5–10 procent tabeli, planista często preferuje skanowanie sekwencyjne, ponieważ losowe odczyty ze sterty wymagane przez indeks stają się droższe niż odczytanie wszystkiego po kolei.
Index-Only Scan
Index-Only Scan jest najszybszą z trzech metod. Jeśli każda kolumna potrzebna zapytaniu znajduje się już w indeksie, silnik w ogóle nie odwołuje się do sterty tabeli.
Przykładowe zapytanie wybiera tylko customer_id i filtruje po tej kolumnie, a indeks został utworzony na customer_id. Wszystkie potrzebne dane znajdują się w indeksie, dlatego Postgres raportuje Index Only Scan.
Eliminuje to losowe odczyty ze sterty, które spowalniają zwykłe skanowanie za pomocą indeksu — jest to ogromna korzyść w przypadku szerokich tabel.
EXPLAIN SELECT customer_id FROM orders WHERE customer_id = 42;
Index Only Scan using idx_orders_customer on orders
(cost=0.42..8.44 rows=12 width=4)
Index Cond: (customer_id = 42)Pułapka związana z mapą widoczności
Rekruterzy uwielbiają ten niuans. Skanowanie wyłącznie z indeksu nadal musi potwierdzić, że każdy wiersz jest widoczny dla danej transakcji (MVCC), a sam indeks nie przechowuje informacji o widoczności.
Postgres używa mapy widoczności: jeśli strona jest oznaczona jako all-visible, pomija stertę; w przeciwnym razie musi pobrać wiersz ze sterty. Plan pokazuje wtedy Heap Fetches: N.
Dlatego świeżo zaktualizowana tabela może wykazywać wiele pobrań ze sterty i spowalniać skanowanie wyłącznie z indeksu, dopóki VACUUM nie odświeży mapy widoczności.
Index Only Scan using idx_orders_customer on orders
(actual time=0.01..0.03 rows=12 loops=1)
Heap Fetches: 0Skanowania bitmapowe: rozwiązanie pośrednie
Często pojawia się również czwarta metoda: Bitmap Heap Scan. Planista wybiera ją, gdy predykat pasuje do większej liczby wierszy, niż opłaca się obsłużyć za pomocą zwykłego skanowania indeksu, ale do mniejszej liczby niż w przypadku całej tabeli.
Najpierw tworzy bitmapę lokalizacji pasujących wierszy na podstawie indeksu (Bitmap Index Scan), a następnie pobiera strony sterty w kolejności fizycznej, a nie losowej. Uporządkowane pobieranie jest znacznie tańsze niż rozproszone odczyty wykonywane przez zwykłe skanowanie za pomocą indeksu.
Bitmap Heap Scan on orders (cost=12.0..520.0 rows=8000)
Recheck Cond: (status = 'pending')
-> Bitmap Index Scan on idx_orders_status
(cost=0..12 rows=8000)
Index Cond: (status = 'pending')Dlaczego planista zignorował indeks
Klasyczne pytanie rekrutacyjne brzmi: Dodałem indeks, ale plan nadal wykonuje Seq Scan — dlaczego? Typowe przyczyny:
- Predykat nie jest selektywny, więc skanowanie jest rzeczywiście tańsze.
- Kolumna jest opakowana funkcją:
WHERE lower(email) = ...nie może użyć zwykłego indeksu naemail. - Niezgodność typów wymusza niejawne rzutowanie, które uniemożliwia użycie indeksu.
- Nieaktualne statystyki — należy uruchomić
ANALYZE. - Tabela jest mała, więc skanowanie kilku stron jest szybsze niż ponoszenie narzutu związanego z indeksem.
Przykład diagnozy
Załóżmy, że tabela orders ma indeks na created_at, ale to zapytanie nadal wykonuje skanowanie sekwencyjne:
Winowajcą jest DATE(created_at). Opakowanie kolumny w funkcję oznacza, że nie można użyć indeksu utworzonego na surowej wartości created_at. Rozwiązaniem jest przepisanie zapytania jako predykatu zakresowego, który pozostawia kolumnę bez modyfikacji, albo utworzenie indeksu wyrażeniowego na DATE(created_at).
-- Slow: function on the indexed column
WHERE DATE(created_at) = '2026-01-01'
-- Fast: bare column, range uses the index
WHERE created_at >= '2026-01-01'
AND created_at < '2026-01-02'Porównanie metod
Na rozmowę rekrutacyjną warto zapamiętać następujące porównanie:
- Seq Scan — najlepszy przy zwracaniu dużej części wierszy; sekwencyjne operacje wejścia-wyjścia.
- Index Scan — najlepszy przy selektywnych wyszukiwaniach; przejście po indeksie oraz losowe odczyty ze sterty.
- Bitmap Heap Scan — przy pośredniej liczbie dopasowań; indeks tworzy bitmapę, a następnie wykonywane są uporządkowane odczyty ze sterty.
- Index-Only Scan — najszybszy, gdy indeks zawiera wszystkie potrzebne kolumny, a strony są oznaczone jako all-visible.
Planista wybiera metodę na podstawie szacowanego kosztu, zależnego głównie od selektywności i statystyk.
Wymuszanie testu (i dlaczego nie na produkcji)
Aby udowodnić coś podczas pracy programistycznej, można tymczasowo wpłynąć na wybór planisty: SET enable_seqscan = off; wymusza preferowanie indeksów, dzięki czemu można porównać plany.
Jest to metoda diagnostyczna, a nie rozwiązanie do zastosowania na produkcji. Na rozmowie rekrutacyjnej należy wspomnieć, że prawdziwymi rozwiązaniami są lepsze statystyki, odpowiedni indeks lub przepisanie predykatu, a nie globalne wyłączanie funkcji planisty.
SET enable_seqscan = off;
EXPLAIN ANALYZE SELECT * FROM orders WHERE amount > 100;
SET enable_seqscan = on;Szybkie sprawdzenie
Zapytanie wybiera tylko email i filtruje po email, a na tej kolumnie istnieje indeks B-tree. Plan pokazuje Index Only Scan. Dlaczego jest to szybsze niż zwykłe skanowanie za pomocą indeksu?
Podsumowanie
Najważniejsze informacje o metodach dostępu:
- Seq Scan sprawdza się przy zapytaniach o niskiej selektywności, a Index Scan przy zapytaniach selektywnych.
- Index-Only Scan pomija stertę, gdy indeks zawiera wszystkie potrzebne kolumny; należy zwracać uwagę na
Heap Fetchesi mapę widoczności. - Bitmap Heap Scan stanowi rozwiązanie pośrednie, pobierając strony sterty w kolejności fizycznej.
- Planista podejmuje decyzję na podstawie selektywności i statystyk; funkcje stosowane na kolumnach, niezgodności typów i nieaktualne statystyki powodują ignorowanie indeksu.
Często zadawane pytania
Czy lekcja „Seq Scan a Index Scan i Index-Only” jest bezpłatna?
Tak — pełny tekst „Seq Scan a Index Scan i Index-Only” 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 Interview Prep, przejdź na CoddyKit PRO. Kurs SQL Interview Prep zawiera 4 lekcji w sumie.
Co nauczysz się w „Seq Scan a Index Scan i Index-Only”?
Dlaczego planer wybiera każdą z tych metod i co mówi to o zapytaniu. Ćwiczysz SQL Interview Prep 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 Interview Prep?
Nie wymagamy żadnego doświadczenia. SQL Interview Prep 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 „Seq Scan a Index Scan i Index-Only”?
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 Interview Prep?
Tak. Każda lekcja SQL Interview Prep 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
- Odczytywanie planu EXPLAIN
- Seq Scan a Index Scan i Index-Only
- Algorytmy złączeń: Nested Loop, Hash, Merge
- Wykrywanie i naprawianie wolnych zapytań