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 01cc1cc..0000000 --- a/community/knowledge/performance/call-setloadfields-before-filters.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -bc-version: [all] -domain: performance -keywords: [setloadfields, placement, filter, setrange, query-plan] -technologies: [al] -countries: [w1] -application-area: [all] ---- - -# Call SetLoadFields before filters - -## 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`.