IT tutorials
 
Technology
 

Microsoft Dynamic AX 2009 : .Performance (part 8) - Transaction Performance - Limiting Field Lists

10/28/2013 3:54:41 AM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

3.4 Limiting Field Lists

Most of the X++ select statements in Dynamics AX retrieve all fields on a record, although the values in only a few of the fields are actually used. The main reason for this coding style is that the Dynamics AX application runtime doesn’t report compile-time or run-time errors if a field on a record buffer is accessed and it hasn’t been retrieved from the database. The following X++ code, which selects only the AccountNum field from the CustTable table but evaluates the value of the CreditRating field and sets the CreditMax field, won’t fail because the application runtime doesn’t detect that the fields haven’t been selected.

static void UpdateCreditMax(Args _args)
{
CustTable custTable;
;
ttsbegin;
while select forupdate accountNum from custTable
{
if (custTable.CreditRating == '')
{
custTable.CreditMax = custTable.CreditMax + 1000;
custTable.update();
}
}
ttscommit;
}


This code updates all CustTable records to a CreditMax value of 1000, regardless of the previous value in the database for the CreditRating and CreditMax fields. Adding the CreditRating and CreditMax fields to the field list of the select statement might not solve the problem because the application logic could still update other fields incorrectly because the update method on the table could be evaluating and setting other fields on the same record.

Important

You could, of course, examine the update method for other fields accessed in the method and then select these fields as well, but new problems would soon surface. For example, if you customize the update method to include application logic that uses additional fields, you might not be aware that the X++ code in the preceding example also needs to be customized.


Limiting the field list when selecting records does result in a performance gain, however, because less data is retrieved from the database and sent to the AOS. The gain is even bigger if you can retrieve the fields by using the indexes without lookup of the values on the table. This performance gain can be experienced and the select statements written safely when you use the retrieved data within a controlled scope, such as a single method. The record buffer must be declared locally and not parsed to other methods as a parameter. Any developer customizing the X++ code can easily see that only a few fields are selected and act accordingly.

To truly benefit from a limited field list, you must understand that the Dynamics AX application runtime sometimes automatically adds extra fields to the field list before parsing a statement to the database.

In the following X++ code, you can see how the application runtime adds additional fields and how to optimize some select statements. The code calculates the total balance for all customers in customer group ‘20’ and converts it into the company’s currency unit. The amountCur2MST method converts the value in the currency specified by the currencyCode field to the company’s monetary unit.

static void BalanceMST(Args _args)
{
CustTable custTable;
CustTrans custTrans;
AmountMST balanceAmountMST = 0;
;
while select custTable
where custTable.CustGroup == '20'
join custTrans
where custTrans.AccountNum == custTable.AccountNum
{
balanceAmountMST += Currency::amountCur2MST(custTrans.AmountCur,
custTrans.CurrencyCode);
}
}



When the select statement is parsed to the database, it retrieves all CustTable and CustTrans record fields, even though only the AmountCur and CurrencyCode fields on the CustTrans table are used. The result is the retrieval of more than 100 fields from the database.

You can optimize the field list simply by selecting the AmountCur and CurrencyCode fields from CustTrans and, for example, only the AccountNum field from CustTable, as shown in the following code.

static void BalanceMST(Args _args)
{
CustTable custTable;
CustTrans custTrans;
AmountMST balanceAmountMST = 0;
;
while select AccountNum from custTable
where custTable.CustGroup == '20'
join AmountCur, CurrencyCode from custTrans
where custTrans.AccountNum == custTable.AccountNum
{
balanceAmountMST += Currency::amountCur2MST(custTrans.AmountCur,
custTrans.CurrencyCode);
}
}



As explained earlier, the application runtime expands the field list from the three fields shown in the preceding X++ code example to five fields because it adds the fields used when updating the records. These fields are added even though neither the forupdate keyword nor any of the specific concurrency model keywords are applied to the statement. The statement parsed to the database starts as shown in the following example, in which the RECID column is added for both tables.

SELECT A.ACCOUNTNUM,A.RECID,B.AMOUNTCUR,B.CURRENCYCODE,B.RECID
FROM CUSTTABLE A,CUSTTRANS B


To prevent retrieval of any CustTable fields, you can rewrite the select statement to use the exists join operator, as shown here.

static void BalanceMST(Args _args)
{
CustTable custTable;
CustTrans custTrans;
AmountMST balanceAmountMST = 0;
;
while select AmountCur, CurrencyCode from custTrans
exists join custTable
where custTable.CustGroup == '20' &&
custTable.AccountNum == custTrans.AccountNum
{
balanceAmountMST += Currency::amountCur2MST(custTrans.AmountCur,
custTrans.CurrencyCode);
}
}



This code retrieves only three fields (AmountCur, CurrencyCode, and RecId) from the CustTrans table and none from the CustTable table.

In some situations, however, it might not be possible to rewrite the statement to use exists join. In such cases, including only TableId as a field in the field list prevents the retrieval of any fields from the table. The original example is modified as follows to include the TableId field.

static void BalanceMST(Args _args)
{
CustTable custTable;
CustTrans custTrans;
AmountMST balanceAmountMST = 0;
;
while select tableid from custTable
where custTable.CustGroup == '20'
join AmountCur, CurrencyCode from custTrans
where custTrans.AccountNum == custTable.AccountNum
{
balanceAmountMST += Currency::amountCur2MST(custTrans.AmountCur,
custTrans.CurrencyCode);
}
}



This code causes the application runtime to parse a select statement to the database with the following field list.

SELECT B.AMOUNTCUR,B.CURRENCYCODE,B.RECID
FROM CUSTTABLE A,CUSTTRANS B


If you rewrite the select statement to use exists join or include only TableId as a field, the select statement sent to the database retrieves just three fields instead of more than 100. As you can see, you can substantially improve your application’s performance just by rewriting queries to retrieve only the necessary fields.

3.5 Field Justification

Dynamics AX supports left and right justification of extended data types. With our current releases, nearly all extended data types are left justified to reduce the impact of space consumption because of double and triple byte storage as a result of Unicode enablement. Left justifying also helps performance by increasing the speed of access through indexes.

Where sorting is critical, you can use right justification. This has to be an exception as is clearly evident in our usage within the application layers we ship.

3.6 Other Performance Considerations

You can further improve transactional performance by giving more thought to the design of your application logic. For example, ensuring that various tables and records are always modified in the same order helps prevent deadlocks and ensuing retries. Spending time preparing the transactions before starting a transaction scope to make it as brief as possible can reduce the locking scope and resulting blocking, and ultimately improve the concurrency of the transactions. Database design factors, such as index design and use, are also important.

 
Others
 
- Microsoft Dynamic AX 2009 : .Performance (part 7) - Transaction Performance - Caching - The EntireTable Cache , The RecordViewCache Class
- Microsoft Dynamic AX 2009 : .Performance (part 6) - Transaction Performance - Caching - Record Caches
- Microsoft Dynamic AX 2009 : .Performance (part 6) - Transaction Performance - Set-Based Data Manipulation Operators - The RecordInsertList and RecordSortedList Classes
- Microsoft Dynamic AX 2009 : .Performance (part 5) - Transaction Performance - Set-Based Data Manipulation Operators - The RecordInsertList and RecordSortedList Classes
- Microsoft Dynamic AX 2009 : .Performance (part 4) - Transaction Performance - Set-Based Data Manipulation Operators - The delete_from Operator
- Microsoft Dynamic AX 2009 : .Performance (part 3) - Transaction Performance - Set-Based Data Manipulation Operators - The update_recordset Operator
- Microsoft Dynamic AX 2009 : .Performance (part 2) - Transaction Performance - Set-Based Data Manipulation Operators - The insert_recordset Operator
- Microsoft Dynamic AX 2009 : .Performance (part 1) - Reducing Round-Trips Between the Client and the Server
- Exchange Server 2010 Quick Start Guide : Configuring Recipients (part 3) - Configuring a Postmaster Address, SSL Certificate , Entering the Product Key
- Exchange Server 2010 Quick Start Guide : Configuring Recipients (part 2) - Creating Distribution Groups, Organizational Health
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us