Bottom Line Studio AI
You can't buy your way out of a bad data model
A dashboard took twenty seconds to load. The warehouse was already oversized. Here is the fifteen-minute check that tells you when more compute will never help.
Your team's dashboard is slow, so somebody suggests paying for a bigger data warehouse. You pay. It's still slow.
Here's what's actually going on:
- Before it reads anything, the warehouse has to plan the work. When the data underneath is organized poorly, the planning is the slow part.
- A bigger warehouse only speeds up the reading. It does nothing for the planning — you're paying to speed up the part that was already fast.
- The fix is a simpler data model, not a bigger bill. In the story below, that took a dashboard from twenty seconds to one — on the cheapest warehouse.
Keep reading for how it happened, and the fifteen-minute check that tells you whether more compute will ever help — worth sending to whoever owns the warehouse bill.
The full story
A list view in an internal revenue app took twenty seconds to load. Not a report. Not a nightly batch. A list — the first thing a rep saw when they opened the tool.
The team had already done the obvious thing. They had sized the warehouse up. Twice. It got marginally better, then stopped getting better, and the cost line kept climbing. By the time I looked at it, the working theory was that the dataset had simply outgrown the platform.
It had not. The dataset was small. The query was the problem, and no amount of compute was ever going to fix it, because the expensive part happened before a single row was read.
If a bigger warehouse doesn't make the dashboard faster, the problem isn't the warehouse. Buying a bigger warehouse to fix a bad model is like buying a faster car to fix a wrong address.
What was actually going on
The list view read from a convenience view — the kind every team has. Someone needed one more attribute, so they joined a table. Someone needed a flag, so they wrapped it in another view. Someone needed history, so they stacked more logic on top. Every change was small, reasonable, and reviewed. Nobody ever looked at the whole thing.
When I pulled the compiled plan — the work the engine actually does, not the SQL we wrote — that one view expanded into roughly 219 operations across 81 joins.
Two things follow from that, and both feel backwards:
- Most of the twenty seconds was spent planning, not reading. The warehouse has to untangle a plan that big before it touches any data, and that work happens on a single thread. Adding cores doesn't divide it. Warehouse size speeds up the reading — and the bottleneck was the planning.
- The cache never helped. A view stack that deep tends to produce results the warehouse won't cache, so every single page load paid full price. The team's mental model was "the first load is slow, then it's warm." There was no warm. Only first load, forever.
The fifteen-minute check
Three checks, in order. You don't need to read a 219-operation plan to run them.
- Compare planning time to reading time. Every serious warehouse shows you both. If planning is more than a third of the total, stop tuning infrastructure. You have a model problem.
- Run the same query twice, back to back. If the second run isn't dramatically faster, you're not getting cache hits — find out why before you optimize anything else.
- Count the joins in the compiled plan, not in the SQL you wrote. This is the one people skip. A tidy forty-line query that reads from three views can compile into something enormous.
What we did instead
We didn't tune the view. We replaced it with one purpose-built model for that one screen: just the columns the list needed, joined once, rebuilt on the existing nightly schedule. The query went from untangling 81 joins to reading a table. Twenty seconds became one — on the small warehouse.
And because the result was now cheap and cacheable, the same model could back the filters, the counts, and the drill-down without a second design.
The habit worth stealing
Deep view stacks aren't a discipline failure. They're what happens when a data layer grows one reasonable request at a time and no one is accountable for the shape of the whole. Every individual change passes review. The whole thing never gets one.
So make the whole thing visible. Two habits do most of the work:
- Put a ceiling on view depth, and treat hitting it as the signal to build a real model, not an inconvenience to route around.
- Review compiled plans for anything user-facing — not just the SQL — before it ships to a screen someone opens fifty times a day.
Compute is the easiest thing to buy and the last thing you should reach for. When the answer is "size it up," ask what evidence says the reading is the slow part. If nobody has that evidence, you're about to spend money to learn nothing.