This blog will cover experiences, triumphs, failures, and the like from the perspective of a Dynamics AX Project Manager.
Thursday, February 28, 2008
Creating 'Permanent' Indexes on DataAreaId in Dynamics AX
I've received a couple of comments regarding this post. Let me add two points to my original post. First, this was more informational than an actual suggestion for your own system. As I stated below, if you have an index with only the DATAAREAID column selected as a 'Non-Clustered' index, this will work. If you add any other additional columns, then AX will remove it when a synchronization is ran. One caveat to this - I am doing this in RTM, so there is always the possibility of this not working in a later release of AX like 4.0 SP1 or SP2. While I'm not expecting to get any performance gain, I am expecting to silence the Query Tuning Wizard on requesting these indexes. As with any performance-related change, I'll monitor how this change affects our installation and adjust accordingly. If I find no harm in their existance, I'll probably leave them there.
I appreciate everyone's feedback on this posting...
DB
Below is the original post:
As I get further from our Implementation Date, I'm transitioning from my original job of developer to more of a DBA/Business Analyst role. The primary reason for the DBA role is due to performance becoming increasingly more of an issue as our database grows and the once amateur users maturing into more novice users demanding even more resources out of the system.
As I work towards optimizing indexes, monitoring resources, and optimizing X++ code, I notice that SQL balks a lot at tables missing indexes with only the 'dataareaid' field within it. As I've always known you cannot add an index to the AX database directly, likewise, you cannot add an index to AX's AOT with only the dataareaid field. Today, I stumbled upon a way to actually accomplish this. Most of you may be aware of this already but I've personally never seen a blog entry or MSDN entry on how doing this to satisfy SQL statistics. While this may not optimize the system at all, I do get asked by my boss a lot why I haven't created these indexes to satisfy what SQL believes it should have. I do know I haven't seen any issues from implementing these indexes.
If you'd like to see if this will help in your server's performance, please try this first in your test/dev environment before even considering making this modification in your production environment. I'm sure this 'hack' is not supported nor advised by Microsoft.
If you are unfamiliar with the 'Missing Indexes' query, try running the following query against your SQL database:
SELECT TOP 20
[Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0), avg_user_impact, TableName = statement,
[EqualityUsage] = equality_columns, [InequalityUsage] = inequality_columns,
[Include Cloumns] = included_columns
FROM sys.dm_db_missing_index_groups g
INNER JOIN sys.dm_db_missing_index_group_stats s
ON s.group_handle = g.index_group_handle
INNER JOIN sys.dm_db_missing_index_details d
ON d.index_handle = g.index_handle
ORDER BY [Total Cost] DESC;
This query will give you what SQL believes are the top 20 missing index structures in your database.
If your system is anything like ours, at least 1/5 to 1/10 of these will be Indexes with only the 'DataAreaId' column specified. To add this index in, just go right to the Indexes node within the SQL Table and create an index. Only index on the 'DataAreaId' column and set the index type to 'Non-Clustered'. Click Ok. If you run a synchronization against the table in the AOT, it will not delete the index. If you now rerun the query above you will see the record no longer appears.
You may ask why I even bothered doing this. Well the answer is while the Total Cost and Average User Impact are all relative numbers, over the last several months I have lowered the highest Total Cost to around 10 billion and all of the records between 1 and 10 billion were all missing 'DataAreaId' indexes. After implementing four indexes the SQL statistics said I needed, my highest Total Cost is now only 28 million.
I hope this advice may prove to be helpful or if nothing else serve as a 'Nice to Know'.
DB
Tuesday, January 01, 2008
Happy New Year!
My challenge, opportunity, and resolution for the new year is to update this blog more often. Let's see if I can actually follow through...
I have some new information to post regarding AIF queue management that I've known for a few months now but just have not made the time to formally post.
As with most documentation that you see for setting up a batch server, the instructions either state or imply to run both the AOS service as well as the batch client on the same dedicated server. This may at first seem like a common-sensical notion since the Batch Client, the AOS Service and the data storage all reside on the same system and will ultimately aide in reducing any network bottlenecks of large amounts of batchable transactions running across the network. However, this is not the case because the bottleneck of having both components running on the same system is the memory. Due to the 1.7GB limitation of 32-bit applications, the OS, the AOS, and the client are all contending for the available memory.
Depending on the amount of transactions that you have processing in an hour, or even a day, separating the processes out onto separate servers may not be necessary for you. In our case, we have approximately 1-500 messages measuring between 30-50KB that pass through our AX system via AIF every hour. As a result of the number of messages we process, our 'All-In-One' setup proved to be quite the bottleneck and resulted with us constantly getting 'Out of Memory' errors in our AIF queue. At one point, we had to filter out all messages larger than 200KB simply because even after freeing up all memory available, we still were unable to process those messages and import them through custom file I/O operations. After testing and working Microsoft, we found that separating the AOS Service on a dedicated server and running the client(s) on a separate dedicated server gave us our best potential performance and freed up the client to contend for memory only against the OS and the same with the AOS service.
To further increase our AIF performance, we found that instead of running all four AIF batch processes together in a single client session, separating each of the four out into separate client sessions increased performance. As a result, you are not limited to the four processes being executed in a sequential order but instead they can all three execute independent and even concurrently. Although the issue still exists that the four processes are related and dependent of each other, however, messages that are ready to be processed at the next execution of the batch are not held back from being processed.
For example, the four AIF processing classes are:
- AIFSendGateway
- AIFReceiveGateway
- AIFInboundProcessingService
- AIFOutboundProcessingService
In order to import a message into AX, AIFReceiveGateway must execute to pull the message into the AIF Queue and the AIFInboundProcessingService must execute to process and persist the data to the database. Likewise, to export a message, AIFOutboundProcessingService must retrieve the data from AX package it in the form of a message and write it to the queue before the AIFSendGateway can pick it up and write it to a message. As a result, spliting up the jobs into different batch clients will allow you to make the AIF message passing process closer to a 'real-time' process.
Finally on a separate note, I have just completed reviewing a new book on Dynamics AX that will soon be published. Once the book is officially published, I will post a link to it.
DB
Monday, November 05, 2007
Comment Spam
Sorry for this inconvenience.
DB
Monday, October 08, 2007
AXUG Summit 2007
Just to fill you in now that things have calmed down, here's our implementation story:
My lack of posts for the last four months have not been because I was too lazy but rather because of being overwhelmed with work. Our implementation was rocky but we made it work and persevered as a result. We have a VP who in my opinion is always a stellar performer. He's the sort of guy that even if everyone is looking at doom and gloom, his head is still held very high. If you ever see this guy looking down you better cover your head because the sky is surely falling. In my opinion he had a lot to do with the project's success. When all seemed as if it were about to fall apart, he was there to encourage all of us on the project and cheer us towards success.
My shop is pretty small, less than eight regular IT employees and due to some recent departures is even smaller now. I was and am the only full-time developer for AX in our company during our implementation. I also have been the only person to become technically fluent with AX from installation to configuration to troubleshooting, etc. Why was our implementation this way? To some extent I can blame it on a lean budget but I can also point to our partner.
Hind sight is always 20-20, of course.
We were new to AX. I had just been hired in February 2006 and had the VPC of AX 4.0 Pre-Release given to me in June, no manuals, no documentation, just a job of learning it. Our Project Team was a who's who of the shining stars in the company, one from each functional area of the company. Not one of them had ever heard of AX, and only two or three had ever worked with or knew what an ERP system was. I was the black sheep being from a technical environment and actually having a two month head start on learning it.
Our partner rolled in and immediately setup a project timeline and a go-live date, which we ultimately missed and had to reschedule three times. All seemed as if it were going well until we began official software modification in October. Developer resources from the partner were not cutting it. Each of the three guys who all in total spent less than two weeks with us seemed to have no real idea what was going on. These guys were asking me questions about AX... a scary thought. But the more scary thought was that I actually had the answers. As a result we determined very quickly that either the seasoned resources were tied up (as we were being told, although each of the three guys we received were 'Senior Developers', or seasoned developers did not exist - my personal belief). Before long into the development/modification phase, we hired a previous contractor of another in-house developed system and cut a lower hourly wage for me to teach him AX and X++ and have him at our disposal as needed. This turned out to be a better decision than the partner's own developers.
In the end, we were still allowing our partner to make architectural decisions since they were
I share a glimpse into our implementation to convey a notion to you if you are the customer: Know AX.
While I'm sure most implementations are packaged deals (like ours) where a team arrives and educates you first and then immediately begins the project, I suggest a different approach. If you can work it out, install the product first, allow your technical people and key functional people access to it and all of the training manuals for no less than a month. They need to understand what the product is, how it works in its pure state. Then and only then start the implementation project. If you as the customer rely on your partner 100% you, too, will experience modifications/business processes that were implemented but not fully thought out. The ramifications can be from as simple as a quick rewrite of a function to a complete overhaul in the next major AX release.
If you are a partner, I encourage you to encourage your client to learn what AX has to offer and how it works from the beginning. Even if the Sales Order process looks nothing like what your customer will expect in the end, still encourage them to create an Item that they sell, create a customer, create the ledger accounts, execute a sales order. Make them understand how AX works before you begin consulting them on Architectural changes. In the end you will profit from a long-lasting business relationship rather than a continous finger-pointing who-did-what-wrong conflict.
And in the end, isn't your goal a happy customer and continuous reference?
Hope this helps those of you either in or preparing to enter an AX implementation, or for that matter any ERP or large-scale software implementation project.
DB
P.S. Are we happy with AX? Of course we are, but we weren't there on July 1st, the day we went live. Much massaging, cleanup, multiple phone calls to Fargo, several 36 hour+ days, and six weeks of no weekends or weekdays off had to be experienced before happiness was achieved but all in all we have learned from our mistakes and it has made us a better shop in the end.
Tuesday, July 10, 2007
AIF Email Survey
I'd like to conduct an email survey for anyone this is applicable to and willing to share usage statistics. I'd like to know how your company is fairing with AIF in a live environment. I'm looking for AIF data only, no Commerce Gateway or custom asciiIO/commaIO input/output processes.
If you're interested in participating, please send an email to: david.bowles@yahoo.com. In the subject line, please put 'AIF Survey', without the quotes. In the body, please copy and paste this template with the information you're willing to share filled out:
***************************
Months Running Live on AIF:
Number of Actions Live on AIF:
Number of 'Out of Box' Actions Live on AIF:
Number of 'Customized From Scratch' Actions Live on AIF:
Number of Sales Order-based Actions on AIF:
Number of Purchase Order-based Actions on AIF:
Number of Production-based Actions on AIF:
Number of Inventory-based Actions on AIF:
Number of Accounting-based (AR/AP/GL) Actions on AIF:
Number of external Systems interfacing AX through AIF:
Using AIF to communicate via EDI? Yes or No
If Yes, What EDI Format and Version do you use:
If Yes, also what Message Brokering/Transformation software do you use, if any:
On a daily average, how many errors do you encounter in your AifQueueManager needing correction?
On a daily or monthly average (please specify which) how many AX AIF transactions do you receive? Inbound _____ Outbound _____
What frequency do you process AIF transactions? Minutely, Quarter Hourly, Hourly, Bi-Daily, Nightly, Monthly
How would you classify the performance of AIF in producing/consuming transactions? Slow, Medium, Fast
Based upon your answer above, does AIF's speed meet your expectations? Yes or No
If AIF's speed is Slow or Medium or it's speed does not meet your expectations, have youworked with a DBA on optimizing database transactions during AIF execution to speed upthe transactions?
If so, in comparison prior to the optimization, does AIF run faster, slower, or the same?
What type of business are you?
***************************
I'd like to thank you in advance for sharing this. After a week or so, I'll post the results of the survey. You're welcome to send this to me totally anonymously. I will not be posting any information regarding the submitter. I'm interested in how many implementations are actually using AIF and to what extent as I'm sure all of you who are using it are interested as well.
DB
Friday, June 01, 2007
No, I haven't abandoned this blog...yet! :-)
I apologize for my nearly two month delay on posting any new updates to the blog. I've been incredibly busy, but isn't everyone? We pushed back the go-live to July 1st due to some 'technical' difficulties - not AX related. In the meantime I've been doing a lot of testing and developing some 'new requirements' also.
To top it all off, I have also been preparing for a wedding as I'll be hanging up my bachelor's cap once and for all on June 16, therefore, I'll be out of contact from June 15 through June 24. Once I get back to the states, I'll be sure to respond to any messages you email to me. The week of June 24th I will be preparing for our July 1st go-live, so I'll be unavailable mostly that week and the week following. Once we get AX stabalized I will be back on board making regular posts.
I can't really think of anything new to talk about in terms of Dynamics AX 4.0. I have been working on some simple data exports outside of AIF using the standard asciiIO/commaIO classes. I am finding that AIF works better with smaller amounts of records rather than larger. We have a couple of outbound files that exports more than 60,000 records. We are seeing minutes worth of difference between AIF and asciiIO exports. I'm hoping that Microsoft realizes an opportunity to optimize the AIF for larger record loads in a later release of AX.
Also, I want to thank everyone for their support. I get emails and instant messages daily from you guys and I'm glad to help as much as possible. I look forward to talking to each of you soon!
David Bowles
Thursday, April 12, 2007
Two 'Colorful' Blog Entries of Notability
Kamal's entry on Graph creation in AX:
http://casperkamal.spaces.live.com/blog/cns!9138ED475277CD63!262.entry
Arijit's entry on Color-coding Grid Lines in AX:
http://daxguy.blogspot.com/2007/04/coloring-grids-in-dax.html#links
I will be implementing both of these HowTo's in our implementation once I get my head above water to begin doing some aesthetically pleasing mods to AX.
Thank you Kamal and Arijit in sharing these helpful tips. These explanations are things that I would never have thought to ask the possibility about, mostly due to my tunnel vision toward May 1 :-).
DB
Sunday, April 01, 2007
MVP Award
Thank you,
David Bowles
Thursday, March 29, 2007
XML File Size limitation using FindList AIF Actions
Thursday, March 22, 2007
Passed!
DB
Testing Today...
David
Tuesday, March 06, 2007
Setting AIF To Output All Documents on Outbound Transactions
This field can be found by first opening the 'Endpoints' form in Basic->Setup->Application Integration Framework, then highlighting the Endpoint in question, clicking 'Action Policies', highlighting the outbound action in question, clicking the 'Configure' button, and clicking the 'Setup' tab.
By default, this field is set to 'Yes', which means that AIF will only output the first 1000 records of any AIF outbound transaction where there are more than 1000 records.
Microsoft product screen shot(s) reprinted with permission from Microsoft Corporation.
Wednesday, February 07, 2007
Installing Dynamics AX 4.0 RTM Side-By-Side with 4.0 SP1
1.) Backup the DB of the environment you are trying to duplicate and upgrade to SP1.
2.) Backup the entire Application folder of the environmnet you are trying to duplicate and upgrade to SP1. If you don't know what or where your Application folder is, you probably should proceed any further.
3.) If you have a 4.0 RTM client on the server where your AOS and File Server is located, you must install it.
4.) Make a copy of your Common Folder in the Microsoft Dynamics\4.0\Server\Common location and call it 'Common RTM'. This will allow you to still configure the 4.0 RTM server environments. Otherwise, you will have problems with the new configuration applet saving the RTM configs correctly since SP1 introduces new Clustering settings.
5.) Install Dynamics AX 4.0 SP1, using the steps in the Microsoft Dynamics AX 4.0 SP1 Upgrade Documentation, specifically page 8 and page 9. (Note only installing the Object Server and File Server and possibly the Dynamics AX 4.0 SP1 client if you want to be able to open ONLY the Dynamics AX 4.0 SP1 environment). Note that on Page 9, point #3, you should not include the axsys.aod file in the files you move to Application\Appl\Standard\Old - this will stop you from being able to create an Upgrade Project.
6.) Before Starting the AOS Service, open the Dynamics AX Server Configuration Utility and import/create a new server configuration that puts the new 4.0 SP1 upgraded environment on a different port than your Dynamics AX 4.0 RTM environment.
7.) Start the AOS Service as indicated on the Microsoft Dynamics 4.0 SP1 upgrade document on page 9 point #5. You can continue on with Microsoft's approved steps from this point.
The biggest two points that I can stress about attempting this is:
A.) BACKUP, BACKUP, BACKUP
B.) Don't forget to make a copy of the Common Folder. as stated in #4 above. If you forget this step and try to open a Dynamics AX 4.0 RTM Server configuration file with the Dynamics AX 4.0 SP1 Server configuration applet and save it, you will hose up your server service the next time you stop and start that server service.
Remember, Microsoft does not endorse my steps. These steps worked great for me but may not work so great for you. Please backup and plan accordingly for issues. Please do not take your issues with these steps to Microsoft.
Quick Tip Regarding DB Synchronization Errors
I'm sure most Dynamics AX admins/developers are aware of this but I decided to post it anyway. I didn't know how to fix this error when I encountered it during an attempted upgrade to 4.0 SP1 and also one of the Dynamics AX Technical contractors I worked with on setting up Dynamics AX back in August 2006 also didn't know how to fix the problem and he had worked with Dynamics AX since 2.5 was released.
If you encounter Synchronization errors, view the Application Event Log to determine what caused the error. In my case, there were two tables that contained duplicate data in key fields within multiple records. Because this data was part of the DMO company and there were no other records that were part of any company in use, I simply deleted the tables and re-synchronized. If your records are part of live data, I would advise attempting to correct the anomolies within the database and re-synchronizing.
Hope this helps!
Monday, January 29, 2007
X12 EDI 857/856 Documents
Thanks in Advance!
David
Monday, January 22, 2007
Miscellaneous Topics
Microsoft released an AIF Whitepaper in December that covers just about everything I have posted on my blog regarding AIF configuration. I'm posting the link here because I haven't seen any postings about it on other Dynamics blogs: https://mbs.microsoft.com/customersource/support/documentation/whitepapers/DAX_AIF_Config.htm
We have almost finished all of our AIF development. Now we are concentrating on developing the Invoice output process but finding a slight difficulty due to our interaction with X12 EDI. The X12 version 4010 857 Advance Shipment Notice / Invoice requires that the ASN information appear in a hierarchical format that is similar to:
Shipment
Order
Pallet
Item
The complications with translating to this data structure is that the AIF produces a relational data structure, of which is based upon a Sales Table header, Sales Table detail, and Shipment detail record. For logistical efficiency purposes, the 857 is setup to be hierarchical because you could have a single line item split among one or more Pallets because of a physical limitation on the nunber of items that will fit on one pallet. In order to accommodate for the hierarchical structure, you have to modify AX's functionality, specifically the Shipments table. Within this table you have to add Trailer, Bill Of Lading, Pallet, Item, and Quantity data.
Due to the lack of direct support for X12 4010 EDI Transaction Sets from BizTalk, we decided to utilize MessageWay Solutions MessageWay Managed File Transfer application. It's been a great fit for us since it already has all X12, EDIFACT, and SWIFT EDI formats already integrated into the product. With minimal BASIC programming experience, you can extend the mapping capability past it's basic drag and drop functionality. This also worked much better for us because we wouldn't need a .NET programming on-site to develop C# or VB.NET mapping/translation applets for BizTalk. Although I was not able to get on the testing list, BizTalk 2006 R2 is in Beta now and it reported has all the EDI transaction sets integrated in it.
Finally, I registered for Convergence on Friday. I'm looking forward to attending as this will be my first time. On top of attending MS Convergence, I will also be attending the AXUG Pre-Conference taking place on Sunday afternoon. I encourage everyone to either join AXUG personally or encourage their company to become active in AXUG and attend their regional events.
Thursday, December 14, 2006
VendAccountItemLookup Form
The form is 'vendaccountitemlookup'. This form is used in different areas of AX for use as the vendor field lookup form. So far, I have found it in 'Planned Orders' form within Master Planning and within Inventory Management under the 'References'. I will also place an example screenshot at the bottom of this post.
The problem our engineer had was that the lookup form has three tabs: 'All Vendors', 'According to Trade Agreements', and 'According to External Item Descriptions'. The 'All Vendors' tab only has the Vendor's Name field in it. If you click over to the 'According to Trade Agreements' or 'According to External Item Descriptions', you only see the vendor's account number. Now if you hold your cursor over the field long enough, you get the automated help text, but it disappears after a few seconds. I'm not sure why this wasn't existing functionality, but I am working on modifying this form to include the Vendor name joined to the proper vendor account number for the respective account number in each tab.
The AX Development Team was able to set this field's lookup simply by including the form name in the 'FormHelp' property of the Extended Data Type that represents the Vendor Account field, which in this case the EDT is 'ItemPrimaryVendId'.
I apparently missed this somewhere in the documentation I have read for AX as this being a possibility for assigning a lookup form to a field. To date, I have either coded my lookups dynamically using the systemlookup form within a lookup() method or I have performed it through an autolookup. As you can see this functionality will allow you to create powerful lookups that can even be multi-tabbed.
(VendAccountItemLookup Form)
Microsoft product screen shot(s) reprinted with permission from Microsoft Corporation.
Sunday, December 10, 2006
Update
I have no substantial information to give out on AX this time, unfortunately. I have learned a lot of lessons as a result of having diverted my attention elsewhere for the majority of this past month.
AX 4.0 SP1 has been a distant blip on the radar screen and I was disappointed that it was delayed so long for release. Because of the amount of work that has yet to be completed, I have had to recommend to our project team and management to delay SP1's implementation until after go-live due to our time constraints.
The remainder of this month will be spent getting the AIF side of AX fully running and integrated with our WMS system.
Thursday, November 02, 2006
Custom Validation Modifications to AIF
In general terms, you can make customizations to any of AIF's transactions simply by modifying the appropriate parm[field_name] method within the appropriate Ax[Table] class for the field that you want to add addition customizations on. In my example, I modified the parmItemId method within the AxSalesLine class. Here is the new parmItemId() method with my modification:
public str parmItemId(str _itemId = '')
{
DictField dictField;
ItemId tempItemId;
InventTable tempInventTable;
;
//My custom code to validate ItemId's existence in the Item Master and replace w/ 'InvalidItem' if not
tempItemId = _itemId;
SELECT FIRSTONLY ItemId FROM tempInventTable WHERE tempInventTable.ItemId == tempItemId;
if (tempInventTable.ItemId != _itemId)
{
_itemId = "**INVALIDITEM**";
salesLine.ItemId = _itemId;
salesLine.Name = tempItemId;
}
if (!prmisdefault(_itemId))
{
dictField = new DictField(tablenum(SalesLine),fieldnum(SalesLine,ItemId));
this.validateInboundItemIdString(_itemId,dictField);
if (this.valueMappingInbound())
{
item = _itemId;
}
this.setField(fieldnum(SalesLine, ItemId), _itemId);
}
if (this.valueMappingOutbound())
{
return conpeek(this.axSalesItemId(salesLine.CustAccount,salesLine.ItemId,salesLine.inventDim()),1);
}
else
{
return salesLine.ItemId;
}
}
Although this is my first shot at AIF modification, I would recommend placing your modification above the existing code. The out of the box code does other validations and checks like seeing whether or not AIF should place default data into a field.
Hope this helps!
Friday, October 27, 2006
Stepping through AIF Processing Code
David
