Problem description
On the one hand, it is a common best practice to select only required information from a database, but quite often an entire record is fetched from the database, even though only one field is actually used. It can be compared to driving a car always on the 1st gear - the engine is fully used, but the car cannot drive fast.
On the other hand, there is a static find method design pattern - the method must be used whenever a record is selected by its key. Find method returns the entire record. Is it contradictory to the common best practice? Let's find out.
Solution
The main decision variable for the question is
CacheLookup
property of a table. Let's analyse common cases and compile an algorithm.1. Table
CacheLookup
property set to EntireTableIt is called set-based caching - all records of a table are placed in the cache after the first select. Subsequent select will get record from the cache instead of the database.
It means that
select Field from Table
cannot improve performance, so Table::find().Field
can be used without performance penalty.2. Table
CacheLookup
property set to NotInTTS, Found, FoundAndEmptyIt is called single-record caching - a record is placed in the cache provided that where clause of the select statement matches fields in any unique index.
Find
method is always based on unique key, so again Table::find().Field
can be safely used.The only exception is a specific case, when
CacheLookup
property is set to NotInTTS and a field is selected inside a transaction. select Field from Table
should be used.3. Table
CacheLookup
property set to NoneRecord is not cached, so
select Field from Table
is preferable.4. Find method is not based on unique key
There are table methods in standard code with find prefix, which do not follow design pattern. For example
\Data Dictionary\Tables\CustTable\Methods\findByLedgerDimension
. Regardless of CacheLookup
property a record is not cached.It means that it is preferable to use
select Field from Table
.Conclusions
In the following cases it is best to use
select Field from Table
:-
CacheLookup
property is set to None-
CacheLookup
property is set to NotInTTS and field is selected inside a transaction-
Find
method is not based on unique keyIn all other cases
Table::find().Field
should be used.
Although NotInTTS doesn't use records cached outside transaction, it does put the record into cache and will take it from there if it's needed again inside the same transaction. Therefore it may be worth caching it.
ReplyDeleteAlso note that AX can fetch all fields anyway to be able to populate the cache, therefore replacing find() with a field list may have no effect. (Source: Inside Microsoft Dynamics AX 2012 R3.)