LC0082 - StefanMaron/BusinessCentral.LinterCop GitHub Wiki
Query
or Rec.Find('-')
with Rec.Next()
Consider using a Using Rec.Count()
to determine if a table has exactly one or more records can cause significant performance issues, especially on large tables, as it triggers a full table or index scan.
The 'IF COUNT = 1' Conundrum – Vjeko.com is an absolute must. ***
*** Before making any changes to your code, readingQuery
To get the best performance, simply use a query object.
Whenever you need to look for a specific count of rows on a table (be it 1, or another exact number) you can write a query over that table, and have it return the first primary key field. Then, you set the TOP clause on the resulting SQL SELECT statement through the TOPNUMBEROFROWS function. If you are looking for COUNT = 1, you use TOPNUMBEROFROWS(2). Then, you count how many rows you retrieved.
Using this approach you can approach the blazing fast performance of ISEMPTY, at the expense of having to create one object per table of interest. This won't be that many query objects, because you very rarely need COUNT = 1, and when you do, it may be that the table in question isn't too busy or too populated, so COUNT would be faster anyway no matter what. Large, busy tables are when you need to start worrying about performance of COUNT, and only these tables will require you to write the COUNT-replacement queries.
procedure MyProcedure()
var
GLEntry: Query "G/L Entry";
NumberOfRecords: Integer;
begin
GLEntry.TopNumberOfRows(2); // If you are looking for .Count() = 1, you use .TopNumberOfRows(2) here
GLEntry.SetRange(PostingDate, WorkDate());
GLEntry.Open();
while GLEntry.Read() do
NumberOfRecords += 1;
GLEntry.Close();
end;
query 50100 "G/L Entry"
{
elements
{
dataitem(GLEntry; "G/L Entry")
{
column(EntryNo; "Entry No.") { }
filter(PostingDate; "Posting Date") { }
}
}
}
Find('-')
with Rec.Next()
Rec.Index scans are not slow operations, so COUNT merely accesses indexes to locate rows, and this is in fact extremely fast. Certainly faster than possible row retrievals that FIND('-') will definitely have to do. It takes far more time to locate top 50 rows the retrieve them, than it does to index-scan a much larger number of rows. But the key word here is "much larger". Because no matter how much faster scanning an individual row is than retrieving an individual row, FIND('-') will do only 50 retrievals, while COUNT will go on as long as there are rows.
Checking for exactly one record
if Rec.Count() = 1 then
Can be replaced by
if Rec.Find('-') and (Rec.Next() = 0) then
Checking for more than one record
if Rec.Count() > 1 then
Can be replaced by
if Rec.Find('-') and (Rec.Next() <> 0) then