クレイグの徹底した答えに加えて、私はあなたが参照する本の表紙が言うことを付け加えたかった:
Oracle、DB2、SQL Serverをカバー
そのため、特にPostgreSQLに関する素晴らしいアドバイスになるとは信じていません。すべてのRDBMSは驚くほど異なる可能性があります。
元の質問について少し混乱していますが、本のセクションが100%正しくないことを示す例を次に示します。さらに混乱を避けるため、関連する段落全体を以下に示します。Googleブック検索で確認できます。
データベースは、Indexed_Col IS NOT NULLがカバーする範囲が大きすぎて役に立たないと想定しているため、データベースはこの状態からインデックスに移動しません。まれなケースとして、null以外の値が存在することは非常にまれであるため、考えられるすべてのnull以外の値に対するインデックス範囲スキャンが有益です。そのような場合、すべての可能な値の範囲の安全な下限または上限を把握できれば、Positive_ID_Column> -1またはDate_Column> TO_DATE( '0001/01/01'などの条件で範囲スキャンを有効にすることができます。 、「YYYY / MM / DD」)。
Postgresは実際に(以下の不自然なケースで)インデックスを使用してIS NOT NULL
、推奨されてPositive_ID_Column > -1
いるのような範囲スキャンクルージを追加することなく、クエリを満たすことができます。この特定のケースでPostgresがこのインデックスを選択する理由については、Craigの質問へのコメントと、部分インデックスの使用に関するメモを参照してください。
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;
ます。