Check SQL Server Missing Indexes (and Why They Lie) in 45 Seconds. The "45 Seconds DBA Series". Part 13

Before we dive into today's topic, if you missed my previous post you can take a look at Check Cardinality Estimation Issues in 45 Seconds. Execution Engine | Part 12.

👉 If you found this deep-dive helpful, feel free to check out the ads—your support helps me keep creating high-quality SQL Server content for the community.

Check SQL Server Missing Indexes (and Why They Lie) in 45 Seconds

Execution Engine Deep Dive | Part 13

In this post, you will learn how to extract the highest impact missing indexes from the plan cache and why blindly applying "green text" suggestions can destroy your server's write performance.

🧠 TL;DR BOX

✔️ Use sys.dm_db_missing_index_details to identify gaps the Optimizer noticed during compilation.
✔️ The "Missing Index" feature is a hint, not a command; it doesn't consider existing indexes or write overhead.
✔️ Never create overlapping indexes; consolidate suggestions into existing structures where possible.
✔️ Execution plan suggestions ignore filtered indexes and optimal column ordering.

Hi SQL SERVER Guys and Gals,

We all know how important it is to make every second count when managing SQL Server environments. Most DBAs see the "Missing Index" warning in an execution plan and immediately hit 'Create'. That is a rookie mistake. Today, I'll show you how to audit these suggestions properly and why the Engine sometimes "lies" about what it needs. Let's get to work!

🔍 DIAGNOSIS: The Missing Index Trap

🧠 What it really is: The SQL Server Query Optimizer has a built-in feature that identifies if a query could have performed better if a specific index existed. This data is stored in Dynamic Management Views (DMVs) and displayed as green text in SSMS.

💣 The Catch: The Missing Index feature is "blind" to several critical factors:

  • It doesn't consider write performance. Every index slows down INSERTs and UPDATEs.
  • It doesn't recognize overlapping indexes. It might suggest 10 indexes for the same table that could be solved by one properly designed composite index.
  • It has a limit of 40 columns and does not suggest filtered indexes or consider include column order.

🧪 QUERY: The 45-Second Audit

Don't look at plans one by one. Use this query to find the "Heavy Hitters" currently affecting your entire instance.

-- 🔍 High Impact Missing Index Diagnostic Query
SELECT TOP 20
    [Impact] = (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans),
    [Table] = [statement],
    [Equality_Columns] = equality_columns,
    [Inequality_Columns] = inequality_columns,
    [Included_Columns] = included_columns,
    [Last_User_Seek] = last_user_seek,
    [Create_Statement] = 'CREATE INDEX [IX_' + OBJECT_NAME(d.object_id) + '_' 
        + REPLACE(REPLACE(REPLACE(ISNULL(equality_columns,''),', ','_'),'[',''),']','') 
        + '] ON ' + [statement] 
        + ' (' + ISNULL(equality_columns,'') 
        + ISNULL(CASE WHEN equality_columns IS NOT NULL AND inequality_columns IS NOT NULL THEN ',' END,'') 
        + ISNULL(inequality_columns,'') + ')' 
        + ISNULL(' INCLUDE (' + included_columns + ')','')
FROM sys.dm_db_missing_index_group_stats s
JOIN sys.dm_db_missing_index_groups g ON s.group_handle = g.index_group_handle
JOIN sys.dm_db_missing_index_details d ON g.index_handle = d.index_handle
WHERE [statement] NOT LIKE '%[sys]%'
ORDER BY [Impact] DESC;

🚀 FIX: The Consolidation Method

When you find a "missing index" suggestion, follow these three steps before running the script:

  • ✔️ Check for Overlaps: Use sp_helpindex to see if the table already has an index with the same leading column. If so, simply add the "Included" columns to the existing index.
  • ✔️ Review Column Order: The Optimizer groups by Equality, then Inequality. Ensure the most selective columns are at the front of the key.
  • ✔️ Assess Write/Read Ratio: If a table is 90% writes and 10% reads, a "99% impact" index might actually be a net loss for the system.

🚀 My REAL Strategy

In my 25 years of experience, I’ve seen servers crawl to a halt because a DBA added 50 "Missing Indexes" in a single afternoon. The Optimizer is selfish. It wants the perfect index for *that specific query* without caring about the other 5,000 queries running on that table. My strategy? If a missing index suggestion has less than 80% impact or low user seeks, ignore it. Focus only on the top 5 "High Impact" results and always try to expand an existing index rather than creating a new one.

📊 TAKEAWAY

Indexes are a double-edged sword. Use the DMVs to find the pain points, but use your brain to design the solution. A leaner index strategy always beats a "green text" strategy in high-concurrency environments.

📢 Support the Blog: Did you find this deep-dive helpful? The ads you see here are selected to reflect your interests. If a partner's offer catches your eye, give it a look! Your engagement helps me continue publishing premium SQL Server content for the community.

Biondi Luca @2026 - Sharing over 25 years of Gained Knowledge for Passion. Share if you like my posts!

🧠 Master SQL Server Performance Hub

Expand your knowledge with my latest deep-dives and performance guides.

Don't forget to check my April 2026 Recap for a complete monthly summary.

Comments

I Post più popolari

Speaking to Sql Server, sniffing the TDS protocol

SQL Server, find text in a Trigger, Stored Procedures, View and Function. Two ways and what ways is better

SQL Server, execution plan and the lazy spool (clearly explained)