You seem to expect that rows with
NULL values are excluded from a B-tree index automatically, but that's not the case. Those are indexed as well and can be searched for. However, since:
access_type... is null in 90% of cases
that's hardly useful in your case. Such common values hardly ever make sense in an index to begin with, be it
NULL or any other value. Exclude
NULL values from the index with a partial index.
CREATE INDEX planet_osm_polygon_accesstype_index ON planet_osm_polygon (access_type) WHERE access_type IS NOT NULL;
Should be much smaller and thus faster.
Remember that you may have to include the same
WHERE condition in queries to make Postgres realize it can apply the partial index.
Related answers with more details:
- http://dba.stackexchange.com/questions/27681/unexpected-seq-scan-when-doing-query-against-boolean-with-value-null/27693#27693Unexpected Seq Scan when doing query against boolean with value NULL
- http://dba.stackexchange.com/questions/62566/join-table-on-some-conditions/62570#62570Join table on some conditions