Skip to content
Web Development5 min read

Database Performance Optimisation: Slow Queries, Indexes, Execution Plans and Measurement

How to optimise database performance: find slow queries, read execution plans, add the right indexes, tune connections and caching, fix data models and measure.

01

How do you optimise database performance?

Measure first to find the queries that consume the most time, read their execution plans, fix them with better indexes, query changes or data model changes, tune connection pools, add caching where data is read often and changes rarely, separate analytics from transactions, and verify each change with before-and-after measurements on your actual database engine. Bigger hardware comes last.

This guide is for developers and engineering leads working with relational databases such as PostgreSQL and MySQL. Specific commands and behaviours differ by engine and version, so validate recommendations against your database's documentation. For wider scaling, see scaling SaaS applications.

02

Key takeaways

  • Rank queries by total time, not just slowest single run.
  • Read execution plans before and after every change.
  • Index for real query patterns; remove unused indexes.
  • Fix N+1 queries and unbounded result sets in the application.
  • Size connection pools deliberately.
  • Move reporting off the primary database.
  • Verify improvements with measurements under realistic load.
03

Step 1: Find the slow queries

Use the database's own statistics, such as the pg_stat_statements extension in PostgreSQL or the slow query log and Performance Schema in MySQL, plus application tracing that links queries to user requests. Rank by total time (frequency times duration), and look at the worst outliers separately. Note the parameters that make queries slow; the same query can be fast for one tenant and slow for another.

04

Step 2: Read the execution plan

Use EXPLAIN to see the planned approach and, in PostgreSQL, EXPLAIN ANALYZE to run the query and see actual rows and timings (PostgreSQL); MySQL also provides EXPLAIN and EXPLAIN ANALYZE (MySQL). Look for full scans of large tables, large differences between estimated and actual rows (often stale statistics), expensive sorts and nested loops over many rows. Run ANALYZE-type statistics updates where estimates are wrong.

05

Step 3: Index for the queries you actually run

  • Index columns used in selective filters and joins.
  • Use composite indexes in the order queries filter and sort; check the plan uses them.
  • Consider partial or covering indexes where your engine supports them.
  • Avoid indexing low-selectivity columns alone.
  • Remove unused and duplicate indexes; they slow writes.
  • Create indexes on large tables in ways that avoid long locks, per your engine's guidance.
06

Step 4: Fix queries and data access patterns

Many problems are in the application: N+1 queries that issue one query per row, selecting every column when few are needed, unbounded result sets without pagination, and functions on indexed columns that prevent index use. Fix these in the data-access layer. Keep transactions short to reduce lock contention, and batch writes where possible.

07

Step 5: Connections, caching and workload separation

Size connection pools to what the database can handle; too many connections can be slower than fewer. Use a pooler where many application instances connect. Cache data that is read often and changes rarely, with clear invalidation; see caching strategy. Move reporting and analytics to replicas or a separate store so they do not compete with transactions.

08

Step 6: Data modelling

Some performance problems are design problems: missing foreign keys and indexes on join columns, wide tables with rarely used columns, storing structured data in unindexed text, or one table serving incompatible access patterns. Archiving old data and partitioning very large tables by time or tenant can help, at the cost of complexity. Change models incrementally with backward-compatible migrations.

09

Step 7: Measure and keep measuring

Record baseline latency and throughput for key queries, test changes under realistic data volumes and load, and compare. Add database metrics and slow-query alerts to monitoring so regressions are caught early; see application monitoring and observability.

10

Common mistakes

  • Tuning without measuring.
  • Adding indexes for every column.
  • Scaling hardware to hide N+1 queries.
  • Running reports on the primary at peak times.
  • Testing on tiny datasets that never show the problem.
11

For related guides, see multi-tenant SaaS architecture, architecture review, business intelligence dashboards for moving reporting off the primary database, and cloud cost optimisation.

12

Conclusion

Database performance work is a measurement loop: find the costly queries, understand their plans, fix indexes, queries and data access, separate workloads, and verify. Validate every recommendation against your engine and version, and leave hardware upgrades until the software is efficient.

Is your database slowing your application?

ZSpace Labs is an India-based, remote-first technology studio working with Australian and international businesses on web application performance. If it would help to find and fix the slow queries, we are happy to talk it through.

Start a Project
FAQ

Common questions.

Measure. Find which queries take the most total time and which are slowest, using your database's statistics, slow query logs or application tracing. Optimising queries that rarely run or are already fast wastes effort. Fix the top few by total time first, then re-measure.

Get in touch

Have a project in mind?

Whether you're building a new digital product, improving an existing website, or looking to automate part of your business — let's talk.