Software & Applications · Service 14

When the slow part is underneath the site.

Caching hides a slow database until it cannot. Schema design and query performance decide whether a system stays quick as data grows — and almost every site that "got slower over time" got slower here, not in the front end.

The pattern is consistent. A site launches fast because there are two hundred rows in every table. Two years later there are two hundred thousand, a report page takes eleven seconds, and everyone blames the hosting. Better hosting buys a little time and considerable expense. Fixing the query usually costs less and lasts longer.

Measured, not guessedIndexes with reasons Schema built to growNo blind rewrites
See what an index does
rows scanned returned sequential scan

Query lab

Four changes, and what each one actually does

A worked example: an orders report on a table of roughly 240,000 rows. Toggle the changes and watch the plan and the timing respond.

These are the four adjustments that resolve the majority of real-world slowness, in roughly the order of impact. None of them involve buying a bigger server. The point of showing the plan alongside the timing is that the plan is the evidence — a query that got faster for a reason you cannot name will get slow again for a reason you cannot name either.

Query


        

Execution plan

estimated

The classic

One page, hundreds of queries

The single most common performance bug in web applications has a name: N+1. One query fetches a list, then the code runs another query for every item in it — invisibly, inside a loop, usually inside a template.

It is easy to miss because each individual query is fast. Nothing looks wrong in the code, and it performs perfectly in development where the list has five rows. In production with fifty, the page makes fifty-one round trips to the database and takes a second and a half to render. Drag the slider and watch both sides.

8

Naive — a query per row

Eager loaded — two queries

Foundations

Design decisions you cannot cheaply undo

Query tuning fixes symptoms. Schema design decides how many symptoms you will have. These are the choices that are inexpensive at the start and expensive in year three.

A schema is not just where data lives — it is a set of guarantees about what states your data can be in. A well-designed one makes certain bugs structurally impossible: an order cannot reference a customer who does not exist, a price cannot be text, two rows cannot claim the same booking slot. Every guarantee the database does not enforce becomes something the application has to remember to check, in every place, forever.

01

Types that mean something

Money as a decimal, not a float or a string. Dates as dates. Booleans as booleans. Storing everything as text pushes validation into every query that reads it.

02

Foreign keys that are enforced

Relationships declared and enforced by the database, so orphaned records cannot exist. Cleaning up orphans years later is archaeology.

03

Indexes chosen deliberately

An index per query you actually run, not one per column. Every index speeds reads and slows writes, so each needs a reason.

04

Normalised until it hurts

Then denormalised carefully where measurement justifies it. Duplicating data before you have a performance problem creates a consistency problem instead.

05

Nullable means something

NULL should mean "unknown", never "zero" or "false" or "not applicable". Conflating them produces reports that quietly disagree with each other.

06

Room to grow

Identifier sizes, character sets and timezone handling chosen for where the business is going, because changing them on a large live table is an outage.

07

Soft deletes with intent

Deciding early what "deleted" means. Retro-fitting it means auditing every query to add a condition somebody will eventually forget.

08

Migrations, not manual edits

Every schema change scripted, versioned and repeatable, so staging and production cannot drift apart unnoticed.

09

A backup you have restored

An untested backup is a hope. Part of the work is proving a restore actually produces a working system.

Questions

Database work, answered

Our site is slow. Is the database the problem?

Often, but not always — and guessing is expensive. The audit starts by measuring: slow query logs, the actual execution plans of the pages people complain about, and where time is really spent. Sometimes the answer is images and the database is fine.

What is nearly always true is that if the site got slower gradually as data grew, rather than after a specific change, the database is the first place to look.

Will a bigger server fix it?

Temporarily, and at permanent cost. Doubling the hardware might halve the time of a query doing unnecessary work, but the underlying inefficiency remains and returns as data grows. An index that turns a full scan into a lookup is often a thousand-fold improvement, not a doubling.

Sometimes more hardware genuinely is the right answer. We will tell you when that is the case rather than selling optimisation you do not need.

Can you fix this without changing our application code?

Frequently, yes. Indexes and configuration changes are invisible to the application and often deliver most of the improvement. Query rewrites and schema changes need code changes, and N+1 problems are code problems by definition.

We sequence it so the no-code-change wins land first — you feel the difference before committing to anything larger.

Is it risky to change a live database?

It can be, which is why nothing is applied directly. Changes are tested against a copy with production-scale data, because an index that takes two seconds on a test table can lock a large one for minutes. Adding indexes is generally safe and reversible; altering columns on big tables needs an online approach and a planned window.

MySQL, PostgreSQL or something else?

We work with MySQL and MariaDB, which is what most WordPress and WooCommerce sites run, and PostgreSQL for custom applications where its stricter typing and richer features earn their keep.

For an existing system, the honest answer is usually to make what you have work well rather than to migrate. Changing engine is a real project, and it rarely fixes a problem that better queries would not.

What does a database audit include?

A fixed-price review with a written report: schema assessment, index coverage against the queries you actually run, the slowest operations with their plans, configuration review, backup verification, and a prioritised list of changes ranked by impact against effort.

You get the report regardless of whether we do the work. Several clients have handed it to their own developers, which is a perfectly good outcome.

Our WooCommerce store slows down as products grow. Normal?

Common, not inevitable. WordPress stores most data in a key-value meta table, which is flexible and gets expensive at scale — product filtering and reporting are usually the first things to suffer.

There are established ways to address it: targeted indexes, lookup tables for the attributes you filter on, and moving heavy reporting off the live query path. This is one of the more frequent reasons people call.