bcquality/community/knowledge/performance/query-results-bypass-primary-key-cache.md
Stefano Demiliani ebceff2332 knowledge(performance): add community rules for JIT, locks, and false positives
These articles capture BC-specific mechanics agents still invert: partial-record JIT on writes, Reset clearing SetLoadFields, HttpClient inside write transactions, and batched number series, plus negative guidance that stops over-eager Query and IsEmpty "fixes".

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 15:57:58 +02:00

1.5 KiB

bc-version domain keywords technologies countries application-area
all
performance
query
primary-key-cache
get
false-positive
n-plus-one
record-cache
al
w1
all

Query results bypass the primary-key cache

Contributions welcome — open a PR to refine or extend this article.

Description

The Business Central server caches primary-key Get calls within a transaction. Query objects do not use that cache: every Open/Read goes to SQL. avoid-get-inside-loop-on-large-table.md is right when an unbounded inner Get/FindFirst joins two large sets. It is wrong as a blanket rewrite of repeated Get on the same keys. Replacing a cached Get with a Query that re-executes per call can be slower. This file exists so reviewers stop treating every Get inside a loop as a Query candidate.

Best Practice

Keep Record.Get for repeated lookups of the same primary keys in one transaction. Use a Query when the work is a true join or aggregation that the record API would express as nested scans. Do not flag a guarded Get on a repeating key as an N+1 solely because a Query could express the same columns.

See sample: query-results-bypass-primary-key-cache.good.al.

Anti Pattern

Rewriting a helper that Gets Customer by No. on every sales line into a Query opened inside that helper. Distinct line customers still need a lookup; repeating customers were already served from the PK cache. The Query pays SQL every time.

See sample: query-results-bypass-primary-key-cache.bad.al.