I added the index the slow query obviously needs and nothing changed - how do you find out why it is not being used?
A query filtering on a couple of columns takes about two seconds on a table with a few million rows. I added an index covering those columns and the timing did not move at all.
The index exists. I can see it in the schema. It is on the columns in the where clause.
I have looked at the query plan and I can see it is doing a sequential scan, so it is clearly not using it, but I cannot read enough of the plan to work out why. Everything I find explains how to create an index and nothing explains why one would be ignored.
What are the actual reasons an index gets skipped, and how do I tell which one applies to me?
@function_on_column · 3w ago · 2 replies
The reasons are a short list and you can usually identify yours in a couple of minutes.
A function or a cast on the indexed column. If the query says something like lower of a column, or the column cast to a different type, the index on the plain column cannot be used: the planner would have to evaluate the function on every row anyway. This is the most common cause by a distance, and the cast version is sneaky because it is often implicit, inserted because the parameter type does not match the column type.
A leading wildcard in a pattern match. An index can find things that start with something; it cannot find things that end with something.
The wrong column order in a composite index. An index on two columns can serve a query filtering on the first, or on both, but generally not on the second alone. If your filter uses them in the other order than the index declares, it is not usable.
The planner thinks a scan is cheaper. If the filter matches a large fraction of the table, reading it all sequentially genuinely is faster, and the planner is right. This is the case where nothing is wrong.
Stale statistics, covered below.
A type mismatch between the column and the parameter, particularly with an ORM binding a parameter as text against a non-text column.
Reply
Report
@partial_index_fan · 2w ago
The cause that caught me and is not on the list: the index was on the columns but in an order that did not match how the query filters. A composite index is usable from the left, so filtering on the second column alone does not touch it.
Same columns, same index, entirely unused. Order is not cosmetic.
Reply
Report