0Pricing
Coding Interview Prep · Lekcja

Indeksy pokrywające i skanowanie wyłącznie indeksu

Dołączanie kolumn, aby zapytanie nie musiało odczytywać sterty tabeli.

Indeksy pokrywające i skanowanie wyłącznie indeksu to bezpłatna lekcja Coding Interview Prep na CoddyKit. To lekcja 3 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 Coding Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.

Przypomnienie: pobieranie z heapu

Wcześniej dowiedzieli się Państwo, że zwykły B-Tree przechowuje tylko indeksowane kolumny oraz wskaźnik do wiersza, więc po znalezieniu dopasowań przez indeks silnik nadal musi przejść do tabeli, aby odczytać pozostałe kolumny. To przejście to pobranie z heapu — koszt, który ma wyeliminować indeks pokrywający.

Rekruterzy pytają o indeksy pokrywające, aby sprawdzić, czy rozumieją Państwo, dlaczego indeks może w pełni odpowiedzieć na zapytanie bez dostępu do tabeli.

Co oznacza „pokrywanie” zapytania

Indeks pokrywa zapytanie, gdy każda kolumna potrzebna zapytaniu — w SELECT, WHERE, ORDER BY i GROUP BY — znajduje się bezpośrednio w indeksie.

W takim przypadku silnik odczytuje wyłącznie indeks i nigdy nie odwiedza tabeli. PostgreSQL nazywa to operacją Index-Only Scan; w SQL Server i innych systemach używa się określenia indeks pokrywający. Korzyścią jest mniej odczytów stron i szybsze zapytania.

Przykład: zapytanie pokryte przez indeks

Załóżmy, że zapytanie potrzebuje tylko customer_id i order_date. Indeks złożony obejmujący dokładnie te kolumny zawiera wszystko, o co pyta zapytanie, więc można na nie odpowiedzieć wyłącznie na podstawie indeksu.

CREATE INDEX idx_orders_cust_date
  ON orders (customer_id, order_date);

-- Covered: both selected columns are in the index
SELECT customer_id, order_date
FROM orders
WHERE customer_id = 42;

Jedna dodatkowa kolumna przerywa pokrywanie

Dodanie kolumny, której indeks nie zawiera, powoduje utratę pokrywania — silnik musi pobrać dane z heapu, aby ją odczytać.

Kolumny total nie ma w indeksie, więc mimo że customer_id steruje wyszukiwaniem, dla każdego pasującego wiersza trzeba pobrać dane z heapu, aby odczytać total.

-- NOT covered: total is not in the index, forces heap fetches
SELECT customer_id, order_date, total
FROM orders
WHERE customer_id = 42;

Klauzula INCLUDE

Mogliby Państwo dodać total jako czwartą kolumnę kluczową, ale jeśli nigdy nie filtrują Państwo po tej kolumnie ani nie sortują według niej, marnuje to miejsce w porządku sortowania drzewa. Lepszym narzędziem jest INCLUDE (obsługiwane przez PostgreSQL i SQL Server): przechowuje dodatkowe kolumny wyłącznie w liściach indeksu jako dane dodatkowe, a nie jako część klucza sortowania.

Zapytanie jest teraz pokryte bez rozbudowywania przeszukiwanej części indeksu.

CREATE INDEX idx_orders_cust_date_inc
  ON orders (customer_id, order_date)
  INCLUDE (total);

-- Now covered: total is carried in the leaf
SELECT customer_id, order_date, total
FROM orders
WHERE customer_id = 42;

Kolumny kluczowe a kolumny dołączone

Precyzyjne rozróżnienie, które robi dobre wrażenie na rekruterach:

  • Kolumny kluczowe określają porządek sortowania i mogą być używane do wyszukiwania oraz skanowania zakresu. Podlegają regule lewego prefiksu.
  • Kolumny dołączone są przechowywane wyłącznie w liściach jako dodatkowe dane; nie można ich przeszukiwać, ale pozwalają pokryć większą liczbę zapytań.

Zasada praktyczna: kolumny, po których filtrują Państwo lub sortują, należy umieścić w kluczu, a kolumny, które tylko zwracają Państwo w wyniku, w INCLUDE.

MySQL/InnoDB: specyfika indeksu klastrowanego

Proszę pokazać znajomość różnic między dialektami. Tabele InnoDB (MySQL) są klastrowane według klucza głównego: indeksy pomocnicze niejawnie zawierają kolumny klucza głównego. Dlatego indeks pomocniczy automatycznie pokrywa każde zapytanie, które wybiera tylko indeksowane kolumny oraz kolumny klucza głównego — nie jest potrzebna klauzula INCLUDE (MySQL nie ma INCLUDE).

Idea indeksu pokrywającego jest uniwersalna, ale składnia i kolumny dołączane niejako bez dodatkowego kosztu zależą od silnika.

Weryfikowanie operacji Index-Only Scan

Pokrywanie należy potwierdzić za pomocą EXPLAIN. W PostgreSQL w planie pojawi się węzeł Index Only Scan zamiast Index Scan. W EXPLAIN (ANALYZE) należy szukać Heap Fetches: 0 — to jednoznaczny sygnał, że nie nastąpił dostęp do tabeli.

Jeśli oczekiwali Państwo operacji index-only, ale widzą Index Scan z pobieraniem z heapu, oznacza to, że w indeksie brakuje jednej z wybranych kolumn.

EXPLAIN (ANALYZE)
SELECT customer_id, order_date, total
FROM orders
WHERE customer_id = 42;
-- Look for: Index Only Scan ... Heap Fetches: 0

Zastrzeżenie dotyczące visibility map w Postgresie

Warto znać ten subtelny szczegół dotyczący Postgresa, za który można zdobyć dodatkowy punkt: operacja Index-Only Scan nadal może sięgnąć do heapu, jeśli strona nie jest oznaczona jako widoczna dla wszystkich w visibility map. Po dużej liczbie aktualizacji należy uruchomić VACUUM, aby visibility map była aktualna; w przeciwnym razie rośnie wartość Heap Fetches, a korzyść z trybu „index-only” maleje.

-- Keeps the visibility map fresh so index-only scans stay heap-free
VACUUM ANALYZE orders;

Kiedy nie tworzyć szerokiego indeksu pokrywającego

Indeksy pokrywające nie są darmowe. Umieszczenie wielu kolumn w INCLUDE sprawia, że indeks staje się duży, zużywa pamięć podręczną i spowalnia zapisy (każdy odpowiedni zapis aktualizuje indeks). Warto wymienić następujące kompromisy:

  • Świetnie sprawdzają się w przypadku często wykonywanych, wąskich zapytań odczytujących dane.
  • Nie sprawdzają się jako miejsce na każdą kolumnę „na wszelki wypadek”.

Indeks powinien pokrywać istotne zapytanie, a nie cały wiersz.

Jak ująć to podczas rozmowy kwalifikacyjnej

Zwięzłe podsumowanie:

„Indeks pokrywający zawiera każdą kolumnę używaną przez zapytanie, więc silnik odpowiada na nie wyłącznie na podstawie indeksu, wykonując Index-Only Scan i pomijając pobieranie z heapu. Umieszczam przeszukiwane kolumny w kluczu, a kolumny używane tylko do zwracania wyników w INCLUDE, sprawdzam za pomocą EXPLAIN ANALYZE, czy Heap Fetches wynosi zero, i utrzymuję indeks wąski, aby chronić wydajność zapisów”.

Szybki test

Przeanalizuj, które kolumny są objęte indeksem i gdzie należy umieścić każdą z nich.

Podsumowanie: indeksy pokrywające

Najważniejsze informacje:

  • Indeks pokrywa zapytanie, gdy zawiera każdą kolumnę potrzebną zapytaniu, umożliwiając operację Index-Only Scan bez pobierania z heapu.
  • Kolumny kluczowe sterują wyszukiwaniem i podlegają regule lewego prefiksu; kolumny INCLUDE są danymi dodatkowymi przechowywanymi wyłącznie w liściach i służą do pokrywania zapytań.
  • Indeksy pomocnicze InnoDB niejawnie zawierają klucz główny.
  • Należy weryfikować plan za pomocą EXPLAIN (ANALYZE) i sprawdzać Heap Fetches; w Postgresie należy dbać o aktualność VACUUM.
  • Indeksy pokrywające powinny być wąskie, aby chronić wydajność zapisów.

Następnie druga strona medalu: kiedy indeksy faktycznie szkodzą.

Często zadawane pytania

Czy lekcja „Indeksy pokrywające i skanowanie wyłącznie indeksu” jest bezpłatna?

Tak — pełny tekst „Indeksy pokrywające i skanowanie wyłącznie indeksu” 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 Coding Interview Prep, przejdź na CoddyKit PRO. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.

Co nauczysz się w „Indeksy pokrywające i skanowanie wyłącznie indeksu”?

Dołączanie kolumn, aby zapytanie nie musiało odczytywać sterty tabeli. Ćwiczysz Coding 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ąć Coding Interview Prep?

Nie wymagamy żadnego doświadczenia. Coding 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 3 z 4.

Ile czasu zajmuje lekcja „Indeksy pokrywające i skanowanie wyłącznie indeksu”?

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 Coding Interview Prep?

Tak. Każda lekcja Coding 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

  1. Indeksy B-Tree i ich zastosowanie
  2. Kolejność kolumn w indeksie złożonym
  3. Indeksy pokrywające i skanowanie wyłącznie indeksu
  4. Kiedy indeksy szkodzą: zapisy i selektywność
← Powrót do Coding Interview Prep