Go One Layer Deeper

One ordinary line of code, expanded downward. Every layer names what it hides for you, how it fails, and where to learn it properly. Descend as far as the problem requires — and stop.

One SELECT, all the way down
Depth
Declarative SQL says what you want. Everything between that and the bytes on disk is a decision the database made for you — and the reason the same query is fast on Monday and slow on Friday.
1SELECT * FROM users WHERE email = 'alice@example.com';
  1. 1
1/10 layers · Enough to build
Why should an application engineer care?

You do not need to write a query planner. You do need to read what one decided, because "add an index" is sometimes right, sometimes useless, and sometimes the reason writes got slower.

The question this ladder asks

Why is this query actually fast or slow?

What are you delegating to an orm? →
Where this goes wrong in production
  1. ORM lazy loading
  2. N+1 queries
  3. Database load
  4. Latency
  5. Production incident
The lesson behind it →

What are you delegating here?

What are you delegating to an orm?
Database
You write
1const user = await userRepository.findByEmail(email)
The abstraction handles
  • SQL generation for your dialect
  • Parameter binding — which is what makes it injection-safe by default
  • Object ↔ row mapping and type coercion
  • Connection acquisition and release from the pool
  • Change tracking, so save() writes only what changed
Still your responsibility
  • Query behaviour — what SQL this actually produces, and whether it is one statement or fifty
  • Index requirements — the ORM cannot create the index findByEmail needs; it will happily scan without it
  • Transaction boundaries — where the transaction starts, ends, and what isolation level you got by default
  • N+1 risks — lazy loading turns attribute access into a query, invisibly, inside loops
  • Data consistency — cascades, orphans, and what a partial failure leaves behind
Know your escape hatch

When: The generated query is slow, the plan is wrong, or the shape of the read does not match any entity.

Drop to: Raw SQL for that query, and EXPLAIN to read what the database decided.

Keeping the ORM for 95% of the code and writing three hand-tuned queries is the normal outcome, not a failure of the ORM.