Postgres Optimizer not using index scan

Postgres sql does not use the index created on the table

select count(cust) from tableA
where
   (col1 = 1)
    and
    (col2 = 2)
    and
    (col3 betwee 0 and 100)


Index created on col1,col2,col2 and(col1,col2,col3) in that order

Table A has over a million records

The explain plan shows that a Sequential Scan is being done on tableA
Why are the indexes not being used?
aswam1975Asked:
Who is Participating?
 
ctcampbellConnect With a Mentor Commented:
Slight correction...  if the first index column is not selective for the WHERE clause, the optimizer MAY or MAY NOT use the index.  It depends on the actual criteria.  The more selective your index, the more likely it is to be used.  There is no guarantee your index will be used at all, if the optimizer doesn't think it will help.  This is normally more true for small tables that fit entirely in a single data page (or just a few), since the whole pages are read anyway.
0
 
rjkimbleCommented:
First, make sure that your indexes are up to date by running the following commands:

vacuum full analyze tableA;
reindex tableA;

If that doesn't fix things, try this query instead:

select count(cust) from tableA
where
   (col1 = 1)
    and
    (col2 = 2)
    and
    (col3 > = 0 and col3 <= 100)

If that uses the index, then I'd say that the PostgreSQL optimizer needs work.
0
 
ctcampbellCommented:
There could be a couple of reasons for that.

First, it appears that PostgreSQL can only use one index per table.  This is different from MS SQL Server which can actually join two or more indexes to speed processing.  What this means is that you must have a single index that matches (or partially matches) your WHERE conditions.  If you have an index on (col1, col2, col3) then you've got that covered.

The second possibility is index selectivity.  If col1 is not very selective (i.e. only contains a small percentage of distinct values), then the optimizer will not use the index.  This is because an index scan is more intensive, per row, than a table scan (postgres has to read the index page and then read the data pointed to by the index, like a bookmark lookup in SQL Server, I think).  If the index selective enough, then the extra time is offset by reading (much) fewer rows.  Thus, create your index with the most selective (i.e. most unique) column first.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.