27 Oct 2026
Database optimisation: 876ms → 17ms
A factory measurement database where one search took most of a second. Three kinds of change, measured one at a time; the same search now takes 17 ms.
The problem
A process-control application on a factory measurement line keeps its reports in PostgreSQL: 9 million measured points, written into four tables, about 84 points to a report. The operator’s data page searches the recent 522 thousand. One search sends six SQL statements and took 681 ms with no filters and 876 ms with all 30 filters set, on a fast machine; on the original one, seconds. Every column was text, the measured values included, and no table had a key or an index.
Names are general, not the application's. A line joins a column to the table it points to. The other 27 filter fields stay as they were.
What I changed
- Indexes that match the questions: the page’s sort order, the distinct part count, the two dropdowns, and the three most selective filters. With every filter set, the page went from reading 26,301 blocks to 975.
- Numbers stored as numbers: a numeric copy of each measured value, so a filter compares numbers instead of testing text with a regular expression and converting it on every row.
- A table with one row per report: four of the six statements ask about reports, not points; 4,641 rows answer each in about 1 ms.
The result
17 ms instead of 876 with every filter set, 6.9 ms instead of 681 with none: 50 to 100 times faster. Each change was a migration of a few seconds; the indexes and numeric columns take 124 MB beside a 206 MB table, and the application’s original statements kept working after every step.