В дополнение к подробному ответу Крейга я хотел добавить, что на обложке книги, на которую вы ссылаетесь, написано:
Охватывает Oracle, DB2 и SQL Server
Так что я бы не поверил, что он станет хорошим источником советов по PostgreSQL в частности. Каждая СУБД может быть на удивление разной!
Я немного озадачен вашим первоначальным вопросом, но вот пример, показывающий, что раздел книги не на 100% правильный. Чтобы избежать путаницы, вот весь соответствующий параграф, вы можете увидеть его в Поиске книг Google .
База данных предполагает, что Indexed_Col IS NOT NULL охватывает слишком большой диапазон, чтобы быть полезным, поэтому база данных не будет приводить к индексу из этого условия. В редких случаях наличие любого ненулевого значения настолько редко, что сканирование диапазона индекса по всем возможным ненулевым значениям выгодно. В таких случаях, если вы можете определить безопасный нижний или верхний предел диапазона всех возможных значений, вы можете включить сканирование диапазона с условием, например Positive_ID_Column> -1 или Date_Column> TO_DATE ('0001/01/01' , «ГГГГ / ММ / ДД»).
Postgres может на самом деле (в следующем надуманном случае) использовать индекс для удовлетворения IS NOT NULL
запросов без добавления полей сканирования диапазона, как предложено Positive_ID_Column > -1
. См. Комментарии на вопросы Крейга о том, почему Postgres выбирает этот индекс в данном конкретном случае, и примечание об использовании частичных индексов.
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)
Кстати, это Postgres 9.3, но я считаю, что результаты будут примерно одинаковыми на 9.1, хотя он не будет использовать «сканирование только по индексу».
Редактировать: я вижу, что вы прояснили свой первоначальный вопрос, и вы, вероятно, задаетесь вопросом, почему Postgres не использует индекс в простом примере, таком как:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
Возможно, потому что у вас нет строк в таблице. Так что добавьте некоторые тестовые данные и ANALYZE my_table;
.