alguidelines/content/docs/BestPractices/if-isempty-then-findset/index.md
2025-06-04 21:14:27 +02:00

82 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "if not IsEmpty then FindSet"
tags: ["AL","Performance"]
categories: ["Best Practice"]
---
_Created by SosicStefan, Described by SosicStefan_
## Introduction
When retrieving records in Business Central, a common pattern is using `IsEmpty` before calling `FindSet` to check whether data exists. However, this approach is redundant and can lead to unnecessary database queries. Business Centrals runtime already optimizes `FindSet` to avoid unnecessary retrieval operations.
## Why Not Use 'If Not IsEmpty Then FindSet'?
The following pattern:
```al
if not Customer.IsEmpty() then
Customer.FindSet();
```
This introduces inefficiencies due to:
- Redundant checks: Business Central internally wraps FindSet in an IF EXISTS query when repeated on platform level itself.
- Extra queries: Calling IsEmpty separately can lead to duplicate execution of SELECT TOP 1 NULL, slowing down performance.
## How Business Central Optimizes FindSet
Consider the following loop:
```al
internal procedure IsEmptyAndFindSet()
var
Customer: Record Customer;
i: Integer;
begin
for i := 1 to 10 do begin
Customer.SetRange("Country/Region Code", 'RS');
if not Customer.IsEmpty() then
Customer.FindSet();
end;
end;
```
With this code being executed, Business Central will run two queries on SQL:
- One for checking `IsEmpty`
- Second for getting dataset with `FindSet`
![image](isempty-then-findset-query.png)
## Best Practice: Use FindSet Directly
Instead of checking `IsEmpty` first, simply use only `FindSet`:
```al
internal procedure FindSetWithoutIsEmpty()
var
Customer: Record Customer;
i: Integer;
begin
for i := 1 to 10 do begin
Customer.SetRange("Country/Region Code", 'RS');
if Customer.FindSet() then;
end;
end;
```
Initially, Business Central runs a normal `SELECT` query to retrieve the data.
![image](findset-only-firstrun-query.png)
However, after running this query for three times, on fourth time the system switches to an optimized query:
![image](findset-only-after-optimization-query.png)
After optimized query, the platform already applies the `IF EXISTS` logic dynamically. Means that explicitly calling `IsEmpty` before `FindSet` is unnecessary.
Full query execution looks like this:
![image](findset-only-full-flow-query.png)
## Summary
Avoid using if not `IsEmpty` then `FindSet`, as Business Central optimizes `FindSet` at the runtime level. This approach eliminates redundant queries, improves performance, and ensures cleaner code.