SQL> drop table if exists x;
SQL> create table x as select generate_series(1,1000) x;
SQL> create unique index x$uq on x(x);
SQL> insert into x values(null);  
SQL> insert into x values(null); -- 유니크 인덱스지만 널값은 중복이 가능합니다.
SQL> explain analyze select * from x where x=1;
                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Index Only Scan using "x$idx" on x  (cost=0.42..8.44 rows=1 width=4) (actual time=0.184..0.187 rows=1 loops=1)
   Index Cond: (x = 1)
   Heap Fetches: 1
 Total runtime: 0.243 ms
(4 rows)
SQL> explain analyze select * from x where x is null;
                                                  QUERY PLAN                                                   
---------------------------------------------------------------------------------------------------------------
 Index Only Scan using "x$uq" on x  (cost=0.28..8.31 rows=2 width=4) (actual time=0.044..0.047 rows=2 loops=1)
   Index Cond: (x IS NULL)
   Heap Fetches: 2
 Total runtime: 0.093 ms
(4 rows)
-- 오! 널 검색인데 인덱스 스캔을 했네요!!
카달로그를 좀 뒤져볼까요?
SQL> select amname, amsearchnulls from pg_am;
 amname | amsearchnulls 
--------+---------------
 btree  | t              ------  우리가 위에서 생성한 인덱스는 btree 타입의 인덱스입니다.
 hash   | f             
 gist   | t             
 gin    | f             
 spgist | t             
(5 rows)
각 컬럼의 의미
amname : Name of the access method
amsearchnulls :  "Does the access method support IS NULL/NOT NULL searches?" 라고 적혀져 있습니다.
이로서 btree 타입의 인덱스에서는 인덱스 스캔을 통해서 null 검색이 가능하다는걸 확인할수 있었습니다.
오라클하고는 다르네요!