Czytałem tę książkę, która tak mówi
Baza danych zakłada, że Indexed_Col IS NOT NULL obejmuje zbyt duży zakres, aby był użyteczny, więc baza danych nie będzie prowadzić do indeksu z tego warunku.
Rozumiem, że książka ma ponad 10 lat, ale okazała się już całkiem przydatna - używając instrukcji zebranych z jej stron przyspieszyłem zapytanie dziesięciokrotnie.
Ponadto, w prowadzeniu EXPLAIN ANALYZE
na SELECT
zapytania, znalazłem, że żaden z moich indeksy są używane, nawet kiedy przez wszystkich praw, powinny one być.
Zatem moje pytanie brzmi:
Przypuśćmy, że istnieje tabela z kolumną, której definicja kolumny zawiera „NOT NULL” i że istnieje indeks obejmujący tę kolumnę, czy ten indeks mógłby być użyty w zapytaniu tej tabeli, w której kolumny są częścią zapytania?
Lubić:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
źródło
WHERE column IS NOT NULL
może nie używać indeksu, ponieważ, jak mówi książka: „obejmuje zbyt duży zakres, aby był użyteczny”. Jeśli 90% wartości nie jest równe null, sekwak będzie prawdopodobnie również szybszy.NOT NULL
kolumnie dlaIS NOT NULL
zapytania, chyba że ten indeks jest również użyteczny dla innych częściWHERE
klauzuli, filtrów łączenia itp., Lub jest użyteczny dla uporządkowanego skanowania tylko indeksu. Innymi słowy, całkowicie zignoruje nadmiarIS NOT NULL
wNOT NULL
kolumnie i dokona wyboru indeksu na podstawie innych szczegółów. (Patrz edycja, ponowne skanowanie tylko w indeksie).Oprócz dokładnej odpowiedzi Craiga chciałem dodać, że na okładce książki, do której się odwołujesz, napisano:
Dlatego nie ufałbym, że jest to świetne źródło porad w szczególności na temat PostgreSQL. Każdy RDBMS może być zaskakująco inny!
Jestem trochę zdezorientowany co do twojego pierwotnego pytania, ale oto przykład pokazujący, że ta część książki nie jest w 100% poprawna. Aby uniknąć dalszych nieporozumień, oto cały odpowiedni akapit, który można zobaczyć w Google Book Search .
Postgres może faktycznie (w poniższym wymyślonym przypadku) użyć indeksu do zaspokojenia
IS NOT NULL
zapytań bez dodawania bloków skanowania zakresu, jak sugerowanoPositive_ID_Column > -1
. Zobacz komentarze do pytań Craiga, aby dowiedzieć się, dlaczego Postgres wybiera ten indeks w tym konkretnym przypadku, oraz uwagę na temat używania indeksów częściowych.Nawiasem mówiąc, jest to Postgres 9.3, ale uważam, że wyniki byłyby w przybliżeniu podobne do wersji 9.1, chociaż nie użyłby „Skanowania samego indeksu”.
Edycja: Widzę, że wyjaśniłeś swoje pierwotne pytanie i najwyraźniej zastanawiasz się, dlaczego Postgres nie używa indeksu w prostym przykładzie, takim jak:
Prawdopodobnie dlatego, że nie masz żadnych wierszy w tabeli. Dodaj więc dane testowe i
ANALYZE my_table;
.źródło
NOT NULL
, a nie zapytanie używaneIS NOT NULL
jako warunek indeksu. To jest w komentarzach, do których się odwołałeś, ale zaktualizuję pytanie, aby je uwzględnić.Nie opublikowałeś zapytania ani przykładowych danych. Ale najczęstsze przyczyny, dla których indeksy nie są używane, dotyczą objętości.
Indeksy są jak książka telefoniczna, która tłumaczy kolumnę na lokalizację wiersza. Jeśli szukasz tylko kilku wierszy, warto spojrzeć na każdy wiersz w książce telefonicznej, a następnie na wiersz w głównej tabeli.
Ale w przypadku kilku wierszy taniej jest pomijać książkę telefoniczną i powtarzać wszystkie wiersze w głównej tabeli. Z mojego doświadczenia wynika, że punkt krytyczny wynosi około 100 rzędów.
źródło
CREATE INDEX ix_frank ON people(name) WHERE name ='frank'
.NOT NULL