Oprócz dokładnej odpowiedzi Craiga chciałem dodać, że na okładce książki, do której się odwołujesz, napisano:
Obejmuje Oracle, DB2 i SQL Server
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 .
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. W rzadkich przypadkach posiadanie wartości różnej od wartości zerowej jest tak rzadkie, że korzystne jest skanowanie zakresu indeksu dla wszystkich możliwych wartości niepustych. W takich przypadkach, jeśli uda się ustalić bezpieczną dolną lub górną granicę zakresu wszystkich możliwych wartości, można włączyć skanowanie zakresu z warunkiem, takim jak kolumna_pozycyjna_dodatkowa> -1 lub kolumna_data> TO_DATE ('0001/01/01' , „RRRR / MM / DD”).
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 sugerowano Positive_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.
CREATE TABLE bar (a int);
INSERT INTO bar (a) SELECT NULL FROM generate_series(1,1000000);
INSERT INTO bar (a) VALUES (1);
CREATE INDEX bar_idx ON bar (a);
EXPLAIN ANALYZE SELECT * FROM bar WHERE a IS NOT NULL;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Index Only Scan using bar_idx on bar (cost=0.42..8.44 rows=1 width=4) (actual time=0.094..0.095 rows=1 loops=1)
Index Cond: (a IS NOT NULL)
Heap Fetches: 1
Total runtime: 0.126 ms
(4 rows)
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:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
Prawdopodobnie dlatego, że nie masz żadnych wierszy w tabeli. Dodaj więc dane testowe i ANALYZE my_table;
.