skip to content

Eager Plans & Over-Fetching

Eager loading declared on the mapping versus requested per query — default fetch types, join fetches, named plans — and the over-fetch it invites. Asked because the cost is bytes, not statements.

on this pageshow

questions

5

How does declaring a link eager on the mapping differ from fetching it per query, and which choice can a query override?

level: middleimportance: must knowfreq 66%

basics

~20 s

A mapping-level eager declaration is global: every read of the owner pays it, including loads the layer issues itself. A per-query fetch is local to one use case. Queries can usually widen a deferred link, but rarely narrow an eager one.

open as a page

What is a named fetch plan in a data-access layer, and when is one better than naming the fetches inside each query?

level: middleimportance: should knowfreq 48%

basics

~20 s

A named fetch plan is a reusable, named description of which links a read should materialise, declared once and attached to a call. It beats inline fetches when several call sites share one shape, or when the read has no query text - a load by identifier.

open as a page

An endpoint stays inside its statement budget yet is slow and heap-heavy under load - how would over-fetching explain that?

level: seniorimportance: should knowfreq 58%

basics

~20 s

Over-fetching costs bytes, not round trips: wide rows, whole graphs and unbounded collections pulled for a screen that shows a fraction. A statement counter stays flat while transfer, hydration and heap grow, so the budget never trips.

open as a page

As a lead, how would you bound what any single read may pull in a large mapped model where eager defaults have accumulated?

level: principalimportance: should knowfreq 40%

basics

~20 s

Push fetch decisions out of the mapping and into per-use-case plans, keep large values out of the rows that every read touches, cap what a collection fetch may return, and enforce a volume budget in tests - not only a statement count.

open as a page