На додаток до ґрунтовної відповіді Крейга, я хотів додати, що обкладинка книги, на яку ви посилаєтесь, говорить:
Охоплює Oracle, DB2 та SQL Server
Тому я б не вірив, що це є чудовим джерелом порад щодо PostgreSQL, зокрема. Кожен RDBMS може бути напрочуд різним!
Я трохи розгублений у вашому первісному запитанні, але ось приклад, який показує, що розділ книги не на 100% правильний. Щоб уникнути подальшої плутанини, ось весь відповідний параграф, ви можете побачити його в пошуку книг Google .
База даних передбачає, що Indexed_Col НЕ 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;
.