From 09370d126e435c91e0a319ece90ef475f202efc2 Mon Sep 17 00:00:00 2001 From: Jeremy Vyska Date: Fri, 22 May 2026 10:06:03 +0200 Subject: [PATCH] Remove SetLoadFields-ordering article and samples The article claimed SetLoadFields must be called before filters, but call order has no impact on the resulting query plan. Removing the article along with its good/bad AL samples rather than rewriting, since the premise itself is incorrect. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../call-setloadfields-before-filters.bad.al | 25 ----------------- .../call-setloadfields-before-filters.good.al | 24 ---------------- .../call-setloadfields-before-filters.md | 28 ------------------- 3 files changed, 77 deletions(-) delete mode 100644 community/knowledge/performance/call-setloadfields-before-filters.bad.al delete mode 100644 community/knowledge/performance/call-setloadfields-before-filters.good.al delete mode 100644 community/knowledge/performance/call-setloadfields-before-filters.md diff --git a/community/knowledge/performance/call-setloadfields-before-filters.bad.al b/community/knowledge/performance/call-setloadfields-before-filters.bad.al deleted file mode 100644 index 65b64f1..0000000 --- a/community/knowledge/performance/call-setloadfields-before-filters.bad.al +++ /dev/null @@ -1,25 +0,0 @@ -codeunit 50100 "Customer Credit Report" -{ - procedure ReportCreditLimits(StartNo: Code[20]; EndNo: Code[20]) - var - Customer: Record Customer; - begin - // Filters applied first. - Customer.SetRange("No.", StartNo, EndNo); - Customer.SetRange(Blocked, Customer.Blocked::" "); - - // SetLoadFields is too late - the platform has already planned the - // query for the full record. The call is paid for without delivering - // any of the optimization benefit. - Customer.SetLoadFields("No.", Name, "Credit Limit (LCY)"); - - if Customer.FindSet() then - repeat - EmitLine(Customer."No.", Customer.Name, Customer."Credit Limit (LCY)"); - until Customer.Next() = 0; - end; - - local procedure EmitLine(CustNo: Code[20]; Name: Text; CreditLimit: Decimal) - begin - end; -} diff --git a/community/knowledge/performance/call-setloadfields-before-filters.good.al b/community/knowledge/performance/call-setloadfields-before-filters.good.al deleted file mode 100644 index 65a1426..0000000 --- a/community/knowledge/performance/call-setloadfields-before-filters.good.al +++ /dev/null @@ -1,24 +0,0 @@ -codeunit 50100 "Customer Credit Report" -{ - procedure ReportCreditLimits(StartNo: Code[20]; EndNo: Code[20]) - var - Customer: Record Customer; - begin - // 1. Declare the minimal load first, before any filter. - Customer.SetLoadFields("No.", Name, "Credit Limit (LCY)"); - - // 2. Apply filters. - Customer.SetRange("No.", StartNo, EndNo); - Customer.SetRange(Blocked, Customer.Blocked::" "); - - // 3. Iterate; the query loads only the three declared fields. - if Customer.FindSet() then - repeat - EmitLine(Customer."No.", Customer.Name, Customer."Credit Limit (LCY)"); - until Customer.Next() = 0; - end; - - local procedure EmitLine(CustNo: Code[20]; Name: Text; CreditLimit: Decimal) - begin - end; -} diff --git a/community/knowledge/performance/call-setloadfields-before-filters.md b/community/knowledge/performance/call-setloadfields-before-filters.md deleted file mode 100644 index 90d95e8..0000000 --- a/community/knowledge/performance/call-setloadfields-before-filters.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -bc-version: [26..28] -domain: performance -keywords: [setloadfields, placement, filter, setrange, query-plan] -technologies: [al] -countries: [w1] -application-area: [all] ---- - -# Call SetLoadFields before filters - -> **Seed article.** Ported from BC Code Intelligence to seed the community corpus. Community contributors are invited to expand or refine. - -## Description - -`SetLoadFields` is folded into the database query that the subsequent `Find`, `FindSet`, or `FindFirst` executes. When it is called after filters have already been applied, the platform either ignores the specification or is forced into an extra round-trip to reload the narrower column set — negating the optimization. The placement rule is simple and absolute: `SetLoadFields` must come first. - -## Best Practice - -Use a consistent order on every record variable that participates in `SetLoadFields` optimization: declare the record, call `SetLoadFields` with the processing fields, apply `SetRange`/`SetFilter`, then `FindSet` and iterate. The order makes the optimization visible in code review and prevents accidental regressions when filters are refactored. - -See sample: `call-setloadfields-before-filters.good.al`. - -## Anti Pattern - -Setting filters first — because the filter logic is what the reviewer is thinking about — and then adding `SetLoadFields` just before the `FindSet`. The platform has already planned the query with the full column set; the `SetLoadFields` call is paid for without delivering any of the benefit. - -See sample: `call-setloadfields-before-filters.bad.al`.