Why Won't PostgreSQL Use My Covering Index?
Dear Postgres, Why won’t you use my covering index?
Lately I’ve been learning to tune queries running against PostgreSQL, and it’s …
Read Moreon • 6 min read
Should you always index your foreign keys? What if you index them, and then the index never gets used?
Dear SQL DBA,
We recently had a SQL Server performance assessment. It remarked on two things that made me think:
1 ) tables with foreign keys but missing supporting index 2 ) tables with indexes that are not used
But in our case the remark in Case 2 was on a index that supports a foreign key!
Curtain down!
Now to my question, in which cases should you as a rule create indexes to support a foreign key?
Regards, The Indexer Who Can’t Win
LOL. I love this one!
Clearly, the solution is to write some meaningless queries that use every unused foreign key indexes, right? :D

Foreign keys are a great way to make sure you have valid data in a relational database.
I think of this in terms of parents and children. For example, let’s say I have two tables: dbo.FirstName, and dbo.Students.
The dbo.FirstName table is the parent table. It has two columns, FirstNameId, and FirstName. This parent contains the valid, unique list of FirstNames. The FirstNameId column is defined as a Primary Key column.
The dbo.Students table is the child table. It has many columns. FirstNameId is one of the columns.
I can create a Foreign Key constraint on the child dbo.Students.FirstNameId that references the parent, dbo.FirstNames.FirstNameId.
This means that whenever I insert a row into dbo.Students, SQL Server will check and make sure that the FirstNameId I use is a valid row in the parent table, dbo.FirstNames.
You can get creative with foreign keys:
To be clear, you don’t have a choice about indexing on the ‘parent’ side of the foreign key. The referenced parent key column(s) has to have an index. (Primary keys and unique constraints are all backed by an index.)
You have a choice about whether to index the columns in the child table - in my example, on dbo.Students.FirstNameId.
I generally do index the child keys, because it’s very common for queries to join between the parent and child columns of a foreign key So there’s a good likelihood you’re going to need an index there.
Erin Stellato wrote a great post on SQLPerformance.com with example code showing why indexing a foreign key can make a big performance difference. It’s called “The Benefits of Indexing Foreign Keys”.
There will be some times when you want to make an exception. (More on this soon.)

Whomever ran your performance assessment didn’t have time to look at this very deeply – or if they did, they didn’t explain it in detail. I can’t really criticize them too much, I’ve had egg on my own face before.
There’s a couple of possibilities about why indexes on your foreign keys might not be used:
I would look for the “lesser evil”.
To check if an unused index is really a problem, ask:
If either of these are a big concern, I’d consider dropping the index on the foreign keys.
However, I would want to monitor it for some time to make sure that there isn’t a workload that really cares about that index which just hasn’t run in a while.
There’s always an exception, right?
Here are some examples I can think of when I might not want a simple index on a child key:
I actually think it would be a nice feature for SQL Server to index foreign key columns automatically, as long as it let you specify not to do so, and also let you alter/drop the indexes later.
There’s a fun discussion of this on Greg Low’s blog from 2008 in his post, “Indexing Foreign Keys - Should SQL Server Do that Automatically?”
I feel like this is a “nice to have” feature, but I don’t feel strongly about the SQL Server product team spending time on it. They’ve got other features that I’d like to have more, because in this case I think other features help compensate a bit.
SQL Server’s “missing index” feature isn’t perfect, but it’s pretty darn good at complaining. If you forget to index a foreign key that’s critical to queries or if the index gets dropped, SQL Server is pretty likely to start asking for an index.
So if you’re looking at your missing index warnings, you’re likely to figure out that an index on the foreign key column can speed up your queries (maybe without even realizing it’s related to a foreign key).
I do recommend handling the missing index feature carefully, like it’s a small child who really wants candy in the grocery store checkout line. But that’s a story for another day.
So, which is Worse: an Unused Index, or an Un-Indexed Foreign Key? Usually an un-indexed foreign key is worse.
Copyright (c) 2025, Catalyze SQL, LLC; all rights reserved. Opinions expressed on this site are solely those of Kendra Little of Catalyze SQL, LLC. Content policy: Short excerpts of blog posts (3 sentences) may be republished, but longer excerpts and artwork cannot be shared without explicit permission.