From 973f66d0282fa76e2d3d4f4a26593bc6dfaeb890 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 12:43:02 +0000 Subject: [PATCH] knowledge: improve review precision from BCApps PR 7546-neg-dc4dbb701f46583f3b48adea8c1962c2cffd5865 feedback --- .../performance/avoid-get-inside-loop-on-large-table.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/microsoft/knowledge/performance/avoid-get-inside-loop-on-large-table.md b/microsoft/knowledge/performance/avoid-get-inside-loop-on-large-table.md index f77fbfe..df34799 100644 --- a/microsoft/knowledge/performance/avoid-get-inside-loop-on-large-table.md +++ b/microsoft/knowledge/performance/avoid-get-inside-loop-on-large-table.md @@ -13,9 +13,11 @@ application-area: [all] A `Get` or `FindFirst` against another persistent table inside a loop can produce an N+1 access pattern: one outer query followed by repeated inner lookups. Server and primary-key caches can satisfy some `Get` calls, so a source-level `Get` is not proof of one SQL round-trip. The concern is an unbounded loop whose lookup keys are not known to repeat or remain cached. +Severity must scale with the inner table, not just the presence of `Get` inside a loop. A `Get` against a small, bounded master/setup table (for example Allocation Account, Payment Terms, Currency, Number Series — tables with at most a few hundred rows) is not the "large table" anti-pattern this article targets: the row count of the inner table caps total lookup cost regardless of how many outer records are processed, and repeated lookups of the same handful of keys are cheap. Do not raise this to High severity solely because a `Get` sits inside a loop over a large outer set; the outer set size is irrelevant when the inner table itself is small. Also credit an existing guard: a `Get` executed only when an optional foreign-key field is non-blank (`if Rec."Some Code" <> '' then if OtherTable.Get(Rec."Some Code") then ...`) already limits calls to rows that actually reference the inner table, further reducing this to a low-severity, case-by-case observation rather than an unconditional N+1. + ## Best Practice -Use a query object to join the outer and inner tables when the relationship and filters can be expressed as one query. If keys repeat, a dictionary cache can reduce lookups to one per distinct key. `SetLoadFields` can reduce the columns transferred by unavoidable inner reads, but it does not eliminate the N+1 shape and must not be presented as doing so. +Use a query object to join the outer and inner tables when the relationship and filters can be expressed as one query. If keys repeat, a dictionary cache can reduce lookups to one per distinct key. `SetLoadFields` can reduce the columns transferred by unavoidable inner reads, but it does not eliminate the N+1 shape and must not be presented as doing so. Reserve this recommendation, and High severity, for genuinely large inner tables (thousands of rows and growing); for small bounded master/setup tables, a passing note about caching by key is enough — do not demand a joined query rewrite. See sample: `avoid-get-inside-loop-on-large-table.good.al`.