Bardzo prosty przykład - jedna tabela, jeden indeks, jedno zapytanie:
CREATE TABLE book
(
id bigserial NOT NULL,
"year" integer,
-- other columns...
);
CREATE INDEX book_year_idx ON book (year)
EXPLAIN
SELECT *
FROM book b
WHERE b.year > 2009
daje mi:
Seq Scan on book b (cost=0.00..25663.80 rows=105425 width=622)
Filter: (year > 2009)
Dlaczego zamiast tego NIE wykonuje skanowania indeksu? czego mi brakuje?
źródło
Czy przeanalizowałeś tabelę / bazę danych? A co ze statystykami ? W przypadku wielu rekordów, w których rok> 2009, skanowanie sekwencyjne może być szybsze niż skanowanie indeksu.
źródło
Podczas skanowania indeksu głowica odczytu przeskakuje z jednego wiersza do drugiego, co jest 1000 razy wolniejsze niż odczyt następnego bloku fizycznego (w skanowaniu sekwencyjnym).
Tak więc, jeśli (liczba rekordów do pobrania * 1000) jest mniejsza niż całkowita liczba rekordów, skanowanie indeksu będzie działać lepiej.
źródło
@a_horse_with_no_name wyjaśnił to całkiem dobrze. Również jeśli naprawdę chcesz użyć skanowania indeksu, powinieneś generalnie używać ograniczonych zakresów w klauzuli where. np. - rok> 2019 i rok <2020.
W wielu przypadkach statystyki dotyczące tabeli nie są aktualizowane i może nie być to możliwe z powodu ograniczeń. W takim przypadku optymalizator nie będzie wiedział, ile wierszy powinien zająć w roku> 2019. W związku z tym zamiast pełnej wiedzy wybiera skanowanie sekwencyjne. Ograniczone partycje rozwiązują problem w większości przypadków.
źródło