mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-06 09:26:52 +01:00
Merge pull request #17 from microsoft/fix-setloadfields-order-myth
Remove SetLoadFields-ordering article (premise is incorrect)
This commit is contained in:
commit
ae0210dd2f
3 changed files with 0 additions and 75 deletions
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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`.
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue