PostgreSQL/PostGIS spatial index - no speed up

The most efficient index for the query expressed in your question is the one on gid as it is the only column that appears in a where expression:

 CREATE INDEX table_gid ON table (gid);

You can safely drop the gist index as it will only consume space and slow inserts/updates/deletes down.

Long explanation

As I said the most effective index in your case is the one on gid as it will allow the db engine to retrieve rows faster (with retrieval usually being the slowest part of the process). After that it will probably better compute the result of the

  ST_Contains(a.way, b.way)

espression without looking at the index. The reason is that the query planner will likely estimate that the extra cost of looking up the gist index on both columns versus looking up the a.way and b.way values directly is not worth the effort as the total number of rows to look up is probably very small especially if the index is unique.

As a rule of thumb remember that the planner will probably favor a table scan over an index scan for small datasets (dataset sizes are estimated by looking at the table statistics).


As unicoletti said, the gist index in the geometry column would only work if you use ST_Contains() in the WHERE expression.

For instance, if you would like to know all polygons that contain one another, you could use something like this:

SELECT a.gid, b.gid
FROM table AS a, table as b
WHERE a.gid != b.gid and ST_Contains(a.way, b.way)

In this case, depending on the size of your table and the complexity of your geometries, the gist index should provide a significant speed up, as ST_Contains will start by filtering the polygons by comparing their boundary boxes before actually check their complete geometries. You can see a small explanation in the OpenGeo Tutorial.