Database.Middle.How would you detect missing indexes?

Detecting missing indexes is key to optimizing database performance — especially for slow queries or high CPU usage.

Let me walk you through several ways to detect them in PostgreSQL, MySQL, and general techniques.

✅ 1. Use the Query Planner (EXPLAIN)

You can check how a query is executed by the database. If it scans entire tables instead of using an index — that’s a red flag.

🔍 PostgreSQL:

EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'stanley@example.com';

Look for "Seq Scan" = full table scan ❌

If you had an index on email, you’d see "Index Scan"

🔍 MySQL:

EXPLAIN SELECT * FROM users WHERE email = 'stanley@example.com';

If type = ALL → full table scan ❌

If type = ref or const → index is used ✅

🚦 2. Check Slow Query Logs

Both PostgreSQL and MySQL can log slow queries. These are likely missing indexes.

PostgreSQL:

Enable in postgresql.conf:

log_min_duration_statement = 500  # log queries slower than 500ms

MySQL:

Enable slow query log:

SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 0.5;

Then inspect the log and EXPLAIN those queries.

🧠 3. Use Built-in Index Advisor Tools

🔧 PostgreSQL (auto-explain + pg_stat_statements):

  • pg_stat_statements helps you find frequently run or expensive queries.
  • You can pair this with auto_explain to detect missing indexes.
SELECT *
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 10;

Then EXPLAIN those queries.

🧠 SQL Server (DMVs):

SELECT *
FROM sys.dm_db_missing_index_details;

🧠 MySQL (Performance Schema):

MySQL 8+ can suggest indexes through the sys.schema_index_statistics or by looking at performance_schema.events_statements_summary_by_digest.


🔬 4. Use 3rd-Party Tools or Extensions

ToolDB SupportDescription
pg_stat_statementsPostgreSQLShows expensive queries
HypoPGPostgreSQLSimulates indexes without creating them
pt-query-digestMySQL (Percona)Analyzes slow query logs
pgBadgerPostgreSQLParses logs and gives index suggestions
EXPLAIN ANALYZE BuffersPostgreSQLShow block reads for potential indexing needs

⚠️ Common Signs You’re Missing an Index

  • Full table scan on WHERE/ORDER BY columns
  • High CPU usage with low I/O
  • Frequent use of queries like:
    • WHERE email = ?
    • JOIN ON foreign_key
    • ORDER BY created_at DESC
  • Repeated slow queries from the same pattern

🛠️ What to Do When You Detect One

  1. Identify the column(s) used in:
    • WHERE
    • JOIN
    • ORDER BY
  2. Create an index:
CREATE INDEX idx_users_email ON users(email);

Test again with EXPLAIN ANALYZE

✅ Summary

MethodDescription
EXPLAINCheck query plans manually
Slow query logsFind high-latency queries
Statistics extensionsAnalyze frequent queries (e.g. pg_stat)
3rd-party toolsDeeper automated insights
Common patternsDetect joins and filters without indexes