Quantcast
Channel: Dynamics 365 Blog
Viewing all 1498 articles
Browse latest View live

Inside Microsoft Dynamics AX 2012 R3 is out--Get your copy!

$
0
0

Our favorite book “Inside Microsoft Dynamics AX 2012” has been updated for AX 2012 R3 and is now available in both ebook formats. Hard copy will be available on August 21st.

Highlights include:
  • A new chapter about developing companion apps for AX 2012.
  • A new chapter about managing the application life cycle that includes descriptions of the tools that are included with Lifecycle Services.
  • New sections about LINQ support and print management.

Pick up your copy today at:

 


Duplicate consolidation transactions in AX 2012

$
0
0

When we run a consolidation for a period that has already been consolidated, AX looks to see if the transaction exists already in the consolidation company’s consolidation history, and if it does the original transaction is removed and the new one is posted for the new consolidation. AX will not look at the actual ledger transactions themselves, but rather the consolidation history which is contained in the LEDGERCONSOLIDATEHISTREF table.

If you run the consolidation process and you notice transactions for a previous period are being duplicated, the likely cause of the issue is a separation between the ledger transaction (GENERALJOURNALACCOUNTENTRY) and the consolidation history reference (LEDGERCONSOLIDATEHISTREF). The consolidation history reference can be seen in General ledger | Inquiries | Consolidations | Transactions | Actuals. The problematic consolidation duplication occurs when we run a consolidation for a period that has already been consolidated, and does not have the transactions in the consolidation history reference. Since the source that AX looks at is the consolidation history reference rather than the ledger transactions, the new consolidation will post transactions that already exist again if there's no reference to the transaction in LEDGERCONSOLIDATEHISTREF.

To illustrate what this looks like, we'll post a single transaction in the subsidiary company, consolidate the transaction, delete the LEDGERCONSOLIDATEHISTREF (to recreate the data condition), show the duplication, and then how to fix it.

First, here's our original transaction in the subsidiary company:

This transaction is then consolidated, which can be seen in General ledger | Inquiries | Consolidations | Transactions | Actuals:

To show what is supposed to happen when we reconsolidate, let's run the consolidation again and examine the results. We can see that original consolidation's transactions have been removed, and the same transactions have been posted to the new consolidation:

In earlier versions of AX, this form contained a "Delete" button. The most common cause of consolidation duplicate transactions was a user deleting the transaction from this form, which leaves the transaction in the ledger but removes it from the consolidation history. As mentioned earlier, AX uses the LEDGERCONSOLIDATEHISTREF table to identify if a consolidation transaction already exists. By removing the transaction from this form, we're separating the ledger transaction from the consolidation history and the transactions will be duplicated upon reconsolidation. To simulate recreating this issue, we'll delete these records in SQL:

DELETE FROM LEDGERCONSOLIDATEHISTREF WHERE DATAAREAID = 'CEC'

We can see this removed the transactions from General ledger | Inquiries | Consolidations | Transactions | Actuals form, but the transactions still exist in the ledger:

The problem occurs when the data is in this state and we consolidate the same period. AX will look the LEDGERCONSOLIDATEHISTREF table, and since the transaction does not exist there a new one is posted even though it already exists in the system. We'll consolidate again to see the balances have doubled:

This is an issue of damaged data, and the only way to correct this will be in SQL. What we will do to isolate these records is look for any transaction that exists in the consolidation company that does not have a related record in consolidation history reference. This will include all transactions (revaluations, general journals, opening/closing transactions, etc.) so we'll need to restrict it further. Consolidation transactions do not have a voucher associated with them, so we query based on the voucher being blank and the accounting date. If you're not using a voucher on the opening/closing transactions, the following will not work as those transactions will also be removed. Here is what the select statement would look like to isolate these orphaned records, where the accounting date is the date of the subsidiary transaction to be consolidated and "CEC" is the legal entity name:

SELECT * FROM GENERALJOURNALACCOUNTENTRY GJAE
INNER JOIN GENERALJOURNALENTRY GJE ON GJAE.GENERALJOURNALENTRY = GJE.RECID 

INNER JOIN LEDGER L ON GJE.LEDGER = L.RECID
WHERE L.NAME='CEC'
AND ACCOUNTINGDATE BETWEEN '8-1-2014' AND '8-31-2014'
AND GJE.SUBLEDGERVOUCHER = ''
AND
GJAE.RECID NOT IN (SELECT TRANSRECID FROM LEDGERCONSOLIDATEHISTREF WHERE DATAAREAID = 'CEC')

We can see the two orphaned records are returned:

If these transactions that are returned are the same records that are duplicated and you've verified that no other transaction types are included in the data, you can delete these transactions from the system. The query is similar to the select, but deleting from GENERALJOURNALACCOUNTENTRY:

DELETE GJAEFROM GENERALJOURNALACCOUNTENTRY GJAE
INNER JOIN GENERALJOURNALENTRY GJE ONG JAE.GENERALJOURNALENTRY = GJE.RECID 

INNER JOIN LEDGER L ON GJE.LEDGER = L.RECID
WHERE L.NAME='CEC'
AND ACCOUNTINGDATE BETWEEN '8-1-2014' AND '8-31-2014'
AND GJE.SUBLEDGERVOUCHER = ''
AND
GJAE.RECID NOT IN (SELECT TRANSRECID FROM LEDGERCONSOLIDATEHISTREF WHERE DATAAREAID = 'CEC')

Since we are deleting records from GENERALJOURNALACCOUNTENTRY, you will need to rebuild your financial dimension set balances to ensure accurate information throughout the system. Once the rebuild is complete, we can see the trial balance is once again correct:

To ensure the fix is complete, we'll run a final consolidation and show the trial balance remains the same.

We can see future consolidations will process correctly, and the issue of duplicate transactions is resolved. Please note that these queries are not something that should be run in a production system, and these are provided for reference only, and will need to be modified for every environment.

 

Tyler Lewin

Senior Support Engineer - Dynamics AX

 

AX Content: Search for all things Microsoft Dynamics AX

$
0
0

I do it. And I’m sure you do it too. We get into a habit of only using the search tools that we’ve always used. You might use Google, I use Bing…but, did you ever wonder if there were other ways to search for AX-specific information?  Wonder no longer. Listed below are a few of the additional tools or methods that you can use to search for all things AX.

WebSearchAX

If you’ve been around the AX world for a while, I would hope that you already know about this fantastic tool.  WebSearchAX gives you advanced search capabilities specific to AX. Use this tool to search for TechNet and MSDN topics, code examples, white papers,  and blog entries related to AX. You can filter your search results by user role, AX version, AX module, and even by language.

Issue searches

Did you know that Microsoft Dynamics Lifecycle Services has built-in search functionality that lets you search for hotfixes, KB articles, regulatory features, and workarounds for reported issues in AX? Read more about it in the following TechNet topic:  ttp://technet.microsoft.com/EN-US/library/dn268610.aspx.

Searching within TechNet and MSDN topics

So, you found the topic that you want on TechNet or MSDN, but what if that topic is super long? Most browsers have a “find on page” feature that lets you search for words or phrases on a web page. In Internet Explorer, use the CTRL+F shortcut key to open the  Find” toolbar. You can enter a search term in this toolbar when you’re viewing a TechNet or MSDN topic to locate a specific word or phrase in that topic.   

Microsoft Dynamics Community search

When you initially search the Microsoft Dynamics Community site, you get a results list that is not filtered. You can narrow your search results down by using the built-in site filters on the left side of the search results list. You can filter by type of content (Forums,  logs, Comments, Files, Users, etc.) and you can filter by product, author, or tags. I suggest that you always filter your results to show only the Microsoft Dynamics AX product.

Search engines

Listed below are my favorite search string “tricks” that I use to help narrow down my search results in standard search engines.

  • OR, NOT
    You can use OR and NOT in your search string to help you get better results. For example, to search for information about AX 2012, but not AX 2009, you would enter the following search string: AX 2012 NOT 2009. To search for organizational hierarchy or organization structure in AX 2012, you would enter the following search string: AX 2012 organization hierarchy OR AX 2012 organization structure.

 

  • Quotation
    marks “”

    To search for an exact phrase, put quotation marks around your search string. Without quotation marks, when you enter a complete sentence or phrase as a search string, most search engines will ignore articles such as “the” and “and”.

 

  • Image
    size (Bing)

    When I’m searching for an image or diagram, I get frustrated when small, unreadable thumbnails are returned in my image search results. To fix this, I search for images that are larger than 200 pixels by adding imagesize:large to the end of my search string. For example: AX 2012 imagesize:large or Organizational hierarchy imagesize:large.

 

  • Site-specific
    search

    If you are trying to find a topic on a specific site, you can add site:[site URL] to the end of your search string. For example, to find a topic about AX shortcut keys that you know is published on TechNet, you would enter the following search string: AX  shortcut keys site:technet.microsoft.com.

 

  • The wildcard
    For when you remember bits and pieces of a topic title, or a half sentence from a web page that you want to find again, you can use the asterisk (*) symbol as a wildcard in the search string. For example, I vaguely remember seeing a topic with a title that  entioned configuring features in AX. To find this topic, I’d enter the following search string: Configure * features AX 2012.

 

Most common search engines publish a complete list of advanced search string syntax that users can use to enhance their search experience. Bing’s Advanced Operator Reference is published here: http://msdn.microsoft.com/en-us/library/ff795620.aspx (Click the topic link and then refer to the Table of Contents pane on the left side of MSDN to see the entire list of operators).

How do you search for AX-specific information?

Are you a search expert? Or, do you have a unique way to find the AX information that you need? If so, please share your AX search tips with the community by commenting on this post and sharing what you know.

AX Content: Microsoft Dynamics AX form list

$
0
0

Microsoft Dynamics AX has many form topics and searching for and finding help for the topic on TechNet can be a challenge. Help is here. The Information experience team has published a list that contains links to all form Help topics. You can find the Microsoft Dynamics AX form list here or if you are searching through the table of contents on TechNet, the topic is here:

 

There are hundreds of form topics available. To quickly locate the topic you’re looking for, open the Microsoft Dynamics AX form list topic on TechNet. You can use the “find on page” feature that lets you search for words or phrases on a web page. In Internet Explorer, use the CTRL+F shortcut key to open the “Find” toolbar. You can enter either the name or the AOT name of the form in this toolbar.

Here is an example of the type of information you’ll find in a form topic:


As always, comment on this post to let us know how these resources work for you, or send email to the Information Experience team at adocs@microsoft.com.

SEPA Direct Debit: Error message 'SEPA Customer:: The Mandate is not specified'

$
0
0

In some AX 2012 and AX 2012 R2 the error message „CUSTOM-EXCEPTION:: SEPA Customer:: The mandate is not
specified“ occurs trying to generate a SEPA Direct Debit payment.

To solve this issue, please have a look at the attached PDF.

Microsoft Dynamics AX general performance analysis scripts

$
0
0

Did you know there is a set of analysis scripts that come with the tool Performance Analyzer 1.20 and can be used to assess the health of your AX system and identify potential causes of performance issues?

After downloading the tool (see above link), you can find these scripts in the following folders:

  • ..\DynamicsPerf1.20 RC0.zip\DynamicsPerf\DynamicsPerf - Analysis Scripts
  • ..\DynamicsPerf1.20 RC0.zip\DynamicsPerf\Scripts - Dynamics AX

This series of blog posts also includes these scripts and a general performance troubleshooting checklist will follow in another series (linking into these) to assist with interpreting and acting on the results.

This is page 1 of 8. Use the links in the table below to navigate between pages.

- General analysis
Analyse SQL ConfigurationPage 1
Analyse SQL IndexesPage 2
Analyse SQL QueriesPage 3
Analyse BlockingPage 4
Baseline - benchmark queriesPage 5
- AX Specific
Analyse AX ConfigurationPage 6
Analyse AX IndexesPage 7
Analyse AX QueriesPage 8

Analyse SQL Configuration

SQLSERVER_INFO
WINDOWS_VERSION
SQL_SERVICES
DISK_VOLUMES
SQL_REGISTRY
SQL_CONFIGURATION
DATA_BUFFER_CACHE
SQL_DATABASES
SQL_DATABASEFILES
SQL_VLFS
SQL_JOBS
SQL_LOGS
SQL_TRACE_FLAGS
SQL_TRIGGERS
FILE_ALLOCATION_UNIT_SIZE
DISK_SECTOR_ALIGNMENT

---------------------------------------------------------------- --
-- SQLSERVER_INFO
-- SQL Server Installation
----------------------------------------------------------------

USE DynamicsPerf

SELECT *
FROM   SERVERINFO
ORDER  BY STATS_TIME DESC

----------------------------------------------------------------
--
-- WINDOWS_VERSION
--
-- Windows version information for this SQL Server instance
-- Current Service Pack?
-- NOTE: This will be blank if not SQL Server 2008R2 SP1 or later
----------------------------------------------------------------

SELECT *
FROM   SERVER_OS_VERSION_VW

----------------------------------------------------------------
--
--  SQL_SERVICES
--
-- SQL Server Services
--  What account are the services running under?
-- NOTE: This will be blank if not SQL Server 2008R2 SP1 or later
----------------------------------------------------------------

SELECT servicename,
       startup_type_desc,
       status_desc,
       process_id,
       last_startup_time,
       service_account,
       is_clustered
FROM   sys.dm_server_services;

----------------------------------------------------------------
--
--   DISK_VOLUMES
--
-- SQL Server Disk Volumes information for all drives that
-- has a database located on it. 
-- Is free disk space low?
-- NOTE: This will be blank if not SQL Server 2008R2 SP1 or later
----------------------------------------------------------------

SELECT *
FROM   SERVER_DISKVOLUMES

----------------------------------------------------------------
--
--  SQL_REGISTRY
--
-- SQL Server Registry values
--  What Trace flags are set?
-- NOTE: This will be blank if not SQL Server 2008R2 SP1 or later
----------------------------------------------------------------

SELECT *
FROM   SERVER_REGISTRY

----------------------------------------------------------------
--
--   SQL_CONFIGURATION
--
-- SQL configuation issues
-- 1. Max Degree of Parallelism set to 1 ?
-- 2- Is the SQL Build the current build ?
-- 3- AWE enabled on large memory 32bit systems?
-- 4- Is Max Server Memory set to something less than total server memory?
-----------------------------------------------------------------

SELECT *
FROM   SQL_CONFIGURATION_CURR_VW

----------------------------------------------------------------
--
--  DATA_BUFFER_CACHE
--
--   Data Buffer Cache
-- 1. Which database is consuming the largest amount of buffer cache ?
--      are we capturing perf data on that database?
----------------------------------------------------------------
-- By Database

SELECT *
FROM   BUFFER_DETAIL_CURR_VW
ORDER  BY SIZE_MB DESC

/*********************************************************************
--RUN this code in any database to get DB specific buffer information

SELECT 
  db.name, OBJ.NAME ,index_id ,
  COUNT(*)AS CACHED_PAGES_COUNT

FROM sys.dm_os_buffer_descriptors AS BD
    INNER JOIN
    (
        SELECT obj.name AS NAME
            ,index_id ,ALLOCATION_UNIT_ID
        FROM sys.allocation_units AS AU
            INNER JOIN sys.partitions AS P
   
                ON AU.CONTAINER_ID = P.HOBT_ID
                    AND (AU.type = 1 OR AU.type = 3)
   INNER JOIN sys.sysobjects AS obj
     on obj.id = P.object_id
        UNION ALL
        SELECT obj.name AS NAME  
            ,index_id, ALLOCATION_UNIT_ID
        FROM sys.allocation_units as AU
            INNER JOIN sys.partitions AS P
                ON AU.CONTAINER_ID = P.PARTITION_ID
                    AND AU.type = 2
   INNER JOIN sys.sysobjects AS obj
     on obj.id = P.object_id
    ) AS OBJ
        ON BD.allocation_unit_id = OBJ.ALLOCATION_UNIT_ID
    INNER JOIN sys.databases db ON BD.database_id = db.database_id
WHERE db.name = DB_NAME() and db.state_desc = 'ONLINE'
GROUP BY db.database_id,db.name, OBJ.NAME, index_id
ORDER BY 4 DESC,db.database_id,db.name, OBJ.NAME, index_id

*********************************************************************/

----------------------------------------------------------------
--
--   SQL_DATABASES
--
-- Investigate databases on this SQL instance
-- 
-- Is there more then 1 production database
-- Are there multiple Dynamics production databases AX and CRM as an example
-- Is development or test databases on this SQL instance
----------------------------------------------------------------

SELECT *
FROM   SQL_DATABASES_CURR_VW

----------------------------------------------------------------
--
--  SQL_DATABASEFILES
--
-- Investigate database files
-- 
-- Are the data and log files on the same drive
-- Is the database set to auto-grow
-- Is there 1 tempdb file per CPU core
----------------------------------------------------------------

SELECT *
FROM   SQL_DATABASEFILES_CURR_VW

----------------------------------------------------------------
--
--   SQL_VLFS
--
-- Investigate Virtual Log files for each database LOG file
--  VLF_Count > 10k requires attention
----------------------------------------------------------------

SELECT DATABASE_NAME,FILEID,
COUNT(*) AS VLF_COUNT,
SUM(CASE WHEN STATUS = 0 THEN 1 ELSE 0 END) AS FREE,
SUM(CASE WHEN STATUS != 0 THEN 1 ELSE 0 END) AS INUSE
FROM LOGINFO
GROUP BY DATABASE_NAME,FILEID
ORDER BY DATABASE_NAME,FILEID

----------------------------------------------------------------
--
--   SQL_JOBS
--
-- Investigate SQL Jobs
-- 
-- Is there a database backup job
-- Is there a database maintenance job to rebuild indexes and update statistics
-- Are there jobs that could stress the server
----------------------------------------------------------------

SELECT *
FROM   SQL_JOBS_CURR_VW

----------------------------------------------------------------
--
--  SQL_LOGS
--
-- Investigate SQL Error LOG
-- 
-- Is failed entries?
--
--  NOTE:  If no data in this table, you need to install latest
--         SQL Server cumulative update
----------------------------------------------------------------

SELECT *
FROM   SQLErrorLog
WHERE  LOGTEXT LIKE '%error%'

----------------------------------------------------------------

--
--   SQL_TRACE_FLAGS
--
-- Investigate SQL Trace Flags that are configured

-- 1117 - Evenly grow database files
-- 1118 - Eliminate Mixed Extents (can increase performance at expense of disk space)
-- 1224 - Override lock escalation, only enable on large memory systems
-- 2371 - SQL 2008 R2 SP1 and later, auto-update statistics occurs more frequently
-- 4136 - Causes SQL Optimizer to use Density Vector instead of Histogram [not recommended - alternative solution for parameter sniffing here].
-- 4199 - Enable all optimizer changes implmented since RTM, should almost always have this on
-- 7646 - Trace Flag to reduce contention on Fulltext indexes

 

----------------------------------------------------------------

SELECT *
FROM   TRACEFLAGS

----------------------------------------------------------------
--
--   SQL_TRIGGERS
--
-- Investigate Database Triggers

----------------------------------------------------------------

SELECT * FROM TRIGGER_TABLE

 

----------------------------------------------------------------
--
-- Run the following from a command line on the SQL Server
--  Bytes per Cluster should be 64k
--
--  fsutil fsinfo ntfsinfo f:
--
-- Run the following from a command line on the SQL Server
--
--
--  WMIC /OUTPUT:C:\SQLTRACE\PARTALIGN.html PARTITION GET DeviceID, StartingOffset /FORMAT:htable
--
----------------------------------------------------------------

 

 

 

 

 

 

 

 

 

 

 

 

Microsoft Dynamics AX general performance analysis scripts page 2

$
0
0

This is page 2 of 8 of the general performance analysis scripts online for the Performance Analyser 1.20 tool. See page 1 for the introduction. Use the links in the table below to navigate between pages.

- General analysis
Analyse SQL ConfigurationPage 1
Analyse SQL IndexesPage 2
Analyse SQL QueriesPage 3
Analyse BlockingPage 4
Baseline - benchmark queriesPage 5
- AX Specific
Analyse AX ConfigurationPage 6
Analyse AX IndexesPage 7
Analyse AX QueriesPage 8

Analyse SQL Indexes

INDEXES_BY_SIZE
INDEX_ACTIVITY
COMPRESSED_INDEXES
EXACT_DUPLICATE_INDEXES
SUBSET_DUPLICATE_INDEXES
INCLUDED_COLUMN_INDEXES
UNUSED_INDEXES
TABLES_WITHOUT_CLUSTERED_INDEX
ADJUST_CLUSTERED_INDEXES
INDEXES_BEING_SCANNED
SEARCH_QUERY_PLANS_FOR_INDEX_USAGE

-- --------------------------------------------------------------
--
--   INDEXES_BY_SIZE
--
-- List top 100 Largest Tables, Investigate for data retention
-- purposes or incorrect application configuration such as logging
----------------------------------------------------------------

USE DynamicsPerf

SELECT TOP 100 DATABASE_NAME,
               TABLE_NAME,
               Sum(CASE
                     WHEN INDEX_DESCRIPTION LIKE 'CLUSTERED%'
                           OR INDEX_DESCRIPTION LIKE 'HEAP%' THEN PAGE_COUNT * 8 / 1024
                   END)   AS SIZEMB_DATA,
               Sum(CASE
                     WHEN INDEX_DESCRIPTION LIKE 'NONCLUSTERED%' THEN PAGE_COUNT * 8 / 1024
                   END)   AS SIZEMB_INDEXES,
               Count(CASE
                       WHEN INDEX_DESCRIPTION LIKE 'NONCLUSTERED%' THEN TABLE_NAME
                     END) AS NO_OF_INDEXES,
               Max(CASE
                     WHEN ( DATA_COMPRESSION > 0 )
                          AND ( INDEX_DESCRIPTION LIKE 'CLUSTERED%'
                                 OR INDEX_DESCRIPTION LIKE 'HEAP%' ) THEN 'Y'
                     ELSE 'N'
                   END)   AS DATA_COMPRESSED,
               Max(CASE
                     WHEN ( DATA_COMPRESSION > 0 )
                          AND ( INDEX_DESCRIPTION LIKE 'NONCLUSTERED%' ) THEN 'Y'
                     ELSE 'N'
                   END)   AS INDEXES_COMPRESSED
FROM   INDEX_STATS_CURR_VW
GROUP  BY DATABASE_NAME,
          TABLE_NAME
ORDER  BY 3 DESC

-- --------------------------------------------------------------
--
--   INDEX_ACTIVITY
--
-- List Activity by table, Investigate for activity
-- purposes or incorrect application configuration such as logging
----------------------------------------------------------------

SELECT DATABASE_NAME,
       TABLE_NAME,
       CASE
         WHEN ( Sum(USER_UPDATES + USER_SEEKS + USER_SCANS
                    + USER_LOOKUPS) = 0 ) THEN NULL
         ELSE ( Cast(Sum(USER_SEEKS + USER_SCANS + USER_LOOKUPS) AS DECIMAL) / Cast(Sum(USER_UPDATES + USER_SEEKS + USER_SCANS
                                                                                        + USER_LOOKUPS) AS DECIMAL) )
       END                                         AS RatioOfReads,
       CASE
         WHEN ( Sum(USER_UPDATES + USER_SEEKS + USER_SCANS
                    + USER_LOOKUPS) = 0 ) THEN NULL
         ELSE ( Cast(Sum(USER_UPDATES) AS DECIMAL) / Cast(Sum(USER_UPDATES + USER_SEEKS + USER_SCANS
                                                              + USER_LOOKUPS) AS DECIMAL) )
       END                                         AS RatioOfWrites,
       Sum(USER_SEEKS + USER_SCANS + USER_LOOKUPS) AS TotalReadOperations,
       Sum(USER_UPDATES)                           AS TotalWriteOperations,
       Sum(USER_UPDATES + USER_SEEKS + USER_SCANS
           + USER_LOOKUPS)                         AS TotalOperations
FROM   INDEX_STATS_CURR_VW    /*sys.dm_db_index_usage_stats*/
GROUP  BY DATABASE_NAME,
          TABLE_NAME
--order by TotalOperations desc
--order by TotalReadOperations desc
ORDER  BY TotalWriteOperations DESC

 

-- --------------------------------------------------------------
--
--  COMPRESSED_INDEXES
--
-- Find indexes that are compressed. 
----------------------------------------------------------------

SELECT *
FROM   INDEX_STATS_CURR_VW
WHERE  DATA_COMPRESSION > 0
ORDER  BY USER_UPDATES DESC

 

-- --------------------------------------------------------------
--
--    EXACT_DUPLICATE_INDEXES
--
-- Tables that have 2 or more indexes with the exact same key
-- Trust me, this happens.
--  NOTE:  If you are using included columns the indexes may be unique
----------------------------------------------------------------

SELECT DATABASE_NAME,
       TABLE_NAME,
       INDEX_KEYS,
       Count(*)
FROM   INDEX_STATS_CURR_VW
GROUP  BY DATABASE_NAME,
          TABLE_NAME,
          INDEX_KEYS
HAVING Count(INDEX_KEYS) > 1
ORDER  BY TABLE_NAME

-- --------------------------------------------------------------
--
--    SUBSET_DUPLICATE_INDEXES
--
-- Just as bad (and even more common) are indexes that are a left key
-- subset of another index on same table.  Unless the subsset key is
-- unique, its usefulness is subsumed of the superset key.
-- NOTE:  If you are using included columns the indexes may be unique
----------------------------------------------------------------

SELECT O.DATABASE_NAME,
       O.TABLE_NAME,
       O.INDEX_NAME            AS SUBSET_INDEX,
       O.INDEX_KEYS            AS SUBSET_INDEX_KEYS,
       O.INDEX_DESCRIPTION     AS SUBSET_INDEX_DESCRIPTION,
       O.PAGE_COUNT * 8 / 1024 AS SUBSET_SIZE_MB,
       I.INDEX_NAME            AS SUPERSET_INDEX,
       I.INDEX_KEYS            AS SUPERSET_KEYS
FROM   INDEX_STATS_CURR_VW O
       LEFT JOIN INDEX_STATS_CURR_VW I
              ON I.RUN_NAME = O.RUN_NAME
                 AND I.DATABASE_NAME = O.DATABASE_NAME
                 AND I.TABLE_NAME = O.TABLE_NAME
                 AND I.INDEX_KEYS <> O.INDEX_KEYS
                 AND I.INDEX_KEYS LIKE O.INDEX_KEYS + ',%'
WHERE  O.INDEX_DESCRIPTION NOT LIKE '%UNIQUE%'
       AND I.INDEX_NAME IS NOT NULL
ORDER  BY O.DATABASE_NAME,
          I.TABLE_NAME,
          I.INDEX_KEYS

 

-- --------------------------------------------------------------
--
--   INCLUDED_COLUMN_INDEXES
--
-- Find indexes with high number of include columns
-- This can be indication of table that needs a different clustered index
-- or poorly designed query.  Will cause table size BLOAT and
-- potential blocking issues as SQL updates the included columns
----------------------------------------------------------------

SELECT TOP 100 *
FROM INDEX_STATS_CURR_VW
WHERE INCLUDED_COLUMNS <> 'N/A'
ORDER BY LEN(INCLUDED_COLUMNS) DESC

-- --------------------------------------------------------------
--
--    UNUSED_INDEXES
--
-- Find indexes that are not being used.  If an index enforces
-- a uniqueness constraint, we must retain it.
--
--**************************************************************
-- DO NOT DELETE THESE INDEXES UNLESS YOU ARE SURE YOU HAVE RUN
-- EVERY PROCESS IN YOUR DYNAMICS DATABASE INCLUDING YEAR END !!
--**************************************************************
----------------------------------------------------------------

SELECT PAGE_COUNT * 8 / 1024 AS SIZE_MB,
       *
FROM   INDEX_HISTORICAL_VW
WHERE
  -- criteria for never been used indexes
  USER_SEEKS = 0
  AND USER_SCANS = 0
  -- uncomment next 2 lines if you want to see indexes with very low usages
  --AND USER_SEEKS < 100
  --AND USER_SCANS < 100
  AND INDEX_DESCRIPTION NOT LIKE '%UNIQUE%'
  AND INDEX_DESCRIPTION NOT LIKE '%HEAP%'
  AND (PAGE_COUNT * 8 / 1024) > 0  -- only show indexes consuming space
ORDER  BY 1 DESC

 

-- --------------------------------------------------------------
--
--  TABLES_WITHOUT_CLUSTERED_INDEX
--
-- Tables missing clustered indexes
-- Heaps with multiple non-clustered indexes.
-- Use the following script to identify a good clustered index
-- based solely on user activity
----------------------------------------------------------------

SELECT CLUS.TABLE_NAME,
       CLUS.INDEX_NAME                                      AS HEAP_TABLE,
       CLUS.INDEX_KEYS                                      AS CLUSTERED_KEYS,
       NONCLUS.INDEX_NAME                                   AS NONCLUSTERED_INDEX,
       NONCLUS.INDEX_KEYS,
       ( NONCLUS.RANGE_SCAN_COUNT - CLUS.RANGE_SCAN_COUNT ) AS NONCLUSTERED_VS_CLUSTERED_RANGE_COUNT,
       CLUS.USER_SEEKS                                      AS CLUSTERED_USER_SEEKS,
       CLUS.USER_SCANS                                      AS CLUSTERED_USER_SCANS,
       CLUS.SINGLETON_LOOKUP_COUNT                          AS CLUSTERED_SINGLE_LOOKUPS,
       CLUS.RANGE_SCAN_COUNT                                AS CLUSTERED_RANGE_SCAN,
       NONCLUS.USER_SEEKS                                   AS NONCLUSTERED_USER_SEEKS,
       NONCLUS.USER_SCANS                                   AS NONCLUSTERED_USER_SCANS,
       NONCLUS.SINGLETON_LOOKUP_COUNT                       AS NONCLUSTERED_SINGLE_LOOKUPS,
       NONCLUS.RANGE_SCAN_COUNT                             AS NONCLUSTERED_RANGE_SCANS,
       NONCLUS.USER_UPDATES                                 AS NONCLUSTERED_USER_UPDATES
FROM   INDEX_STATS_CURR_VW CLUS
       INNER JOIN INDEX_STATS_CURR_VW NONCLUS
               ON CLUS.TABLE_NAME = NONCLUS.TABLE_NAME
                  AND CLUS.DATABASE_NAME = NONCLUS.DATABASE_NAME
                  AND CLUS.INDEX_NAME <> NONCLUS.INDEX_NAME
WHERE  CLUS.INDEX_DESCRIPTION LIKE 'HEAP%'
       AND ( ( NONCLUS.RANGE_SCAN_COUNT > CLUS.RANGE_SCAN_COUNT )
              OR ( NONCLUS.SINGLETON_LOOKUP_COUNT > CLUS.SINGLETON_LOOKUP_COUNT ) )
ORDER  BY CLUS.USER_LOOKUPS DESC,
          CLUS.TABLE_NAME,
          ( NONCLUS.RANGE_SCAN_COUNT - CLUS.RANGE_SCAN_COUNT ) DESC

-- ----------------------------------------------------------------------------------------
--
--    ADJUST_CLUSTERED_INDEXES
--
--
-- Find clustered indexes that could be changed
-- to 1 of the non-clustered indexes that has more usage than the clustered index
-- Use the following script to identify the non-clustered index
-- that could be the clustered index based solely on user activity
-- This should be the LAST activty done in a performance tuning session
--
--NOTE - CHANGING CLUSTERED INDEXES WILL TAKE LONG TIME TO DO
--  AND REQUIRES DOWNTIME TO IMPLEMENT
--------------------------------------------------------------------------------------------

SELECT CLUS.TABLE_NAME,
       CLUS.INDEX_NAME                                      AS CLUSTERED_INDEX,
       CLUS.INDEX_KEYS                                      AS CLUSTERED_KEYS,
       NONCLUS.INDEX_NAME                                   AS NONCLUSTERED_INDEX,
       NONCLUS.INDEX_KEYS,
       ( NONCLUS.RANGE_SCAN_COUNT - CLUS.RANGE_SCAN_COUNT ) AS NONCLUSTERED_VS_CLUSTERED_RANGE_COUNT,
       CLUS.USER_SEEKS                                      AS CLUSTERED_USER_SEEKS,
       CLUS.USER_SCANS                                      AS CLUSTERED_USER_SCANS,
       CLUS.SINGLETON_LOOKUP_COUNT                          AS CLUSTERED_SINGLE_LOOKUPS,
       CLUS.RANGE_SCAN_COUNT                                AS CLUSTERED_RANGE_SCAN,
       NONCLUS.USER_SEEKS                                   AS NONCLUSTERED_USER_SEEKS,
       NONCLUS.USER_SCANS                                   AS NONCLUSTERED_USER_SCANS,
       NONCLUS.SINGLETON_LOOKUP_COUNT                       AS NONCLUSTERED_SINGLE_LOOKUPS,
       NONCLUS.RANGE_SCAN_COUNT                             AS NONCLUSTERED_RANGE_SCANS,
       NONCLUS.USER_UPDATES                                 AS NONCLUSTERED_USER_UPDATES
      
FROM   INDEX_STATS_CURR_VW CLUS
       INNER JOIN INDEX_STATS_CURR_VW NONCLUS
         ON CLUS.TABLE_NAME = NONCLUS.TABLE_NAME
            AND CLUS.DATABASE_NAME = NONCLUS.DATABASE_NAME
            AND CLUS.INDEX_NAME <> NONCLUS.INDEX_NAME
WHERE   CLUS.INDEX_DESCRIPTION LIKE 'CLUSTERED%' AND (( NONCLUS.RANGE_SCAN_COUNT > CLUS.RANGE_SCAN_COUNT )
        OR ( NONCLUS.SINGLETON_LOOKUP_COUNT > CLUS.SINGLETON_LOOKUP_COUNT ))
ORDER  BY CLUS.USER_LOOKUPS DESC, CLUS.TABLE_NAME,
          ( NONCLUS.RANGE_SCAN_COUNT - CLUS.RANGE_SCAN_COUNT ) DESC

-- --------------------------------------------------------------
--
--   INDEXES_BEING_SCANNED
--
-- Find non-clustered indexes that are being scanned.  Generally 
-- this will indicate that key columns are out of order compared
-- to query predicates
--
----------------------------------------------------------------

SELECT TOP 100 *
FROM   INDEX_STATS_CURR_VW
WHERE  USER_SCANS > 0
       AND INDEX_DESCRIPTION LIKE 'NONCLUSTERED%'
ORDER  BY USER_SCANS DESC

-- --------------------------------------------------------------
--
--    SEARCH_QUERY_PLANS_FOR_INDEX_USAGE
--
-- Using indexes identifies in the previous query, list queries
-- whose execution plan references a specific index; order by
-- most expensive (logical reads)
--
----------------------------------------------------------------

SELECT TOP 100 *
FROM   QUERY_STATS_CURR_VW
WHERE  QUERY_PLAN_TEXT LIKE '%Index_Name%'
ORDER  BY TOTAL_LOGICAL_READS DESC

 

 

 

Microsoft Dynamics AX general performance analysis scripts page 3

$
0
0

This is page 3 of 8 of the general performance analysis scripts online for the Performance Analyser 1.20 tool. See page 1 for the introduction. Use the links in the table below to navigate between pages.

- General analysis
Analyse SQL ConfigurationPage 1
Analyse SQL IndexesPage 2
Analyse SQL QueriesPage 3
Analyse BlockingPage 4
Baseline - benchmark queriesPage 5
- AX Specific
Analyse AX ConfigurationPage 6
Analyse AX IndexesPage 7
Analyse AX QueriesPage 8

Analyse SQL Queries

EXPENSIVE_QUERIES
MISSING_INDEX_QUERIES
QUERIES_WITH_MULTIPLE_EXECUTION_PLANS
QUERIES_SCANNING_TABLES

USE DynamicsPerf

----------------------------------------------------------------
--
--  EXPENSIVE_QUERIES
--
-- List top 100 most expensive queries
----------------------------------------------------------------

SELECT TOP 100 *
FROM   QUERY_STATS_CURR_VW QS -- Queries from last data collection only
--FROM   QUERY_STATS_VW QS -- Review queries for all data collections

WHERE 
 --Remove queries with comments
 NOT EXISTS (SELECT QUERY_HASH
                   FROM   COMMENTS C
                   WHERE  C.QUERY_HASH = QS.QUERY_HASH)  -- Remove queries that have comments
-- AND  QUERY_HASH = 0x0000000000 -- find a specific query
-- AND SQL_TEXT LIKE '%VALUE%'  -- find all SQL statements that contain a specific text i.e. table name
-- AND QUERY_PLAN_TEXT LIKE '%VALUE%'  -- find all SQL Plans that contain a specific text i.e. index name
-- AND LAST_EXECUTION_TIME > 'XXXXXXX'   -- find all queries that have executed after a specific time
-- AND DATABASE_NAME = 'XXXXXXXXX'       -- find all queries for a specific database
-- AND MAX_ELAPSED_TIME /10 > AVG_ELAPSED_TIME  -- Find all queries potentially getting blocked or paramater sniffing issues

ORDER  BY TOTAL_ELAPSED_TIME DESC -- Queries consuming most TOTAL time on SQL Server

-- ORDER  BY AVG_LOGICAL_READS DESC  -- Queries potentially causing large disk i/o
-- ORDER  BY EXECUTION_COUNT DESC  -- High execution count could be loops in application code
-- ORDER  BY TOTAL_LOGICAL_READS DESC  -- Queries to review to potentially reduce disk i/o

 

----------------------------------------------------------------
--
--    MISSING_INDEX_QUERIES
--
-- Identify queries that the optimizer suspects can be optimized
-- by new or changed indexes:
--
-- NOTE: DO NOT add these indexes verbatim without
--   deep analysis.  Large INCLUDED lists are NOT recommended
--   for ERP solutions
----------------------------------------------------------------

SELECT TOP 100 *
FROM   MISSING_INDEXES_CURR_VW
WHERE  NOT EXISTS (SELECT QUERY_HASH
                   FROM   COMMENTS C
                   WHERE  C.QUERY_HASH = MISSING_INDEXES_CURR_VW.QUERY_HASH) -- Remove queries that have comments
       AND INDEX_IMPACT > 75
       AND EXECUTION_COUNT > 100
       AND AVG_ELAPSED_TIME > 20
       AND AVG_LOGICAL_READS > 1000
ORDER  BY TOTAL_LOGICAL_READS DESC

 

----------------------------------------------------------------
--
--   QUERIES_WITH_MULTIPLE_EXECUTION_PLANS
--
-- List queries that have more than 1 execution plan
-- NOTE:  Only useful on SQL2008 or greater
-- This is for potential parameter sniffing issues
----------------------------------------------------------------

SELECT DATABASE_NAME,
       QUERY_HASH,
       COUNT(QUERY_PLAN_HASH) AS CNT
FROM   QUERY_STATS_CURR_VW
GROUP  BY DATABASE_NAME,
          QUERY_HASH
HAVING COUNT(QUERY_PLAN_HASH) > 1
ORDER  BY CNT DESC

 

----------------------------------------------------------------
--
--   QUERIES_SCANNING_TABLES 
--
-- Find queries scanning a table
----------------------------------------------------------------

SELECT TOP 100 *
FROM   QUERY_STATS_CURR_VW
WHERE  ( QUERY_PLAN_TEXT LIKE '%TABLE SCAN%'
          OR QUERY_PLAN_TEXT LIKE '%INDEX SCAN%' )
--AND QUERY_PLAN_TEXT LIKE '%<Table Name>%'  -- Comment this line to return all tables
ORDER  BY TOTAL_LOGICAL_READS DESC

 

 


Microsoft Dynamics AX general performance analysis scripts page 4

$
0
0

This is page 4 of 8 of the general performance analysis scripts online for the Performance Analyser 1.20 tool. See page 1 for the introduction. Use the links in the table below to navigate between pages.

- General analysis
Analyse SQL ConfigurationPage 1
Analyse SQL IndexesPage 2
Analyse SQL QueriesPage 3
Analyse BlockingPage 4
Baseline - benchmark queriesPage 5
- AX Specific
Analyse AX ConfigurationPage 6
Analyse AX IndexesPage 7
Analyse AX QueriesPage 8

Analyse Blocking

SQLTRACE_BLOCKING
OPTIONAL_BLOCKING_QUERIES 

/*****************  SQLTRACE_BLOCKING **********************************
*
*
*  NOTE:DYNPERF_Default_Trace_Start Job MUST be setup and running
*
*
**************************************************************************/

 

/********* This view reads the Trace files direct
***   from the @PATH parameter on the DYNPERF_Default_Trace_Start job  *******/

SELECT *
FROM   [BLOCKED_PROCESS_VW]
ORDER BY END_TIME DESC

 

--Run in the database to find a key lock

USE DYNAMICSDB   --<-----------------PUT YOUR DBNAME HERE
GO

SELECT o.name,
       i.name
FROM   sys.partitions p
       JOIN sys.objects o
         ON p.object_id = o.object_id
       JOIN sys.indexes i
         ON p.object_id = i.object_id
            AND p.index_id = i.index_id
WHERE  p.hobt_id = 72057709223149568 -- key: 15:72057709223149568(aldk9nn887)  as example

--Run in the database to find an object lock

USE DYNAMICSDB   --<-----------------PUT YOUR DBNAME HERE
GO

SELECT o.name,
       i.name
FROM   sys.partitions p
       JOIN sys.objects o
         ON p.object_id = o.object_id
       JOIN sys.indexes i
         ON p.object_id = i.object_id
            AND p.index_id = i.index_id
WHERE  o.object_id = 72057709223149568 -- object: 15:72057709223149568  as example

--Summarize blocks by resource

SELECT WAIT_RESOURCE,
       COUNT(WAIT_RESOURCE)
FROM   (SELECT WAIT_RESOURCE
        FROM   [BLOCKED_PROCESS_VW]) AS A
GROUP  BY WAIT_RESOURCE
ORDER  BY 2 DESC

 

/******** Read the trace directly  *************/

SELECT E.name,
       F.*
--FROM fn_trace_gettable('C:\SQLTRACE\DYNAMICS_DEFAULT.trc', DEFAULT) F,
--sys.trace_events EXECUTE
FROM   fn_trace_gettable(isnull((SELECT TRACE_FULL_PATH_NAME
                                 FROM   DYNAMICSPERF_SETUP), (SELECT TOP 1 path
                                                              FROM   sys.traces
                                                              WHERE  path LIKE '%DYNAMICS_DEFAULT%')), DEFAULT) F,
       sys.trace_events E
WHERE  EventClass = trace_event_id
ORDER  BY StartTime DESC

     
     

/**********************************************************************************************************
*
*  OPTIONAL_BLOCKING_QUERIES
*
*  NOTE: The DYNPERF_Optional_Polling_for_Blocking must be run for any of the following queries to
*   have data.  This job is not intended to run full time but only optionally when more
*   information is needed for api_cursorfetch sql statements in blocking conditions.
*
*
*
**********************************************************************************************************/

 

/*************************************************************************
Find all lead blockers with a wait time > 2 seconds from most recent to oldest
*************************************************************************/

SELECT *
FROM   BLOCKS_VW
WHERE  BLOCKER_STATUS = 'Lead Blocker'
       AND WAIT_TIME > 2000
ORDER  BY BLOCKED_DTTM DESC

/*************************************************************************
Find all lead blockers from most recent to oldest
*************************************************************************/

SELECT *
FROM   BLOCKS_VW
--WHERE  BLOCKER_STATUS = 'Lead Blocker'
ORDER  BY BLOCKED_DTTM DESC

 

/*************************************************************************
Find all lead blockers with a wait time > 2 seconds on a specific date
  from most recent to oldest
*************************************************************************/

SELECT *
FROM   BLOCKS_VW
WHERE  BLOCKER_STATUS = 'Lead Blocker'
       AND WAIT_TIME > 2000
       AND BLOCKED_DTTM BETWEEN '5/20/2008' AND '5/21/2008'
ORDER  BY BLOCKED_DTTM DESC

/*************************************************************************
  Which applications are the Lead Blocker the most
 
*************************************************************************/

SELECT BLOCKER_PROGRAM,
       COUNT(*) AS NUMBER
FROM   BLOCKS_VW
WHERE  BLOCKER_STATUS = 'Lead Blocker'
GROUP  BY BLOCKER_PROGRAM
ORDER  BY NUMBER DESC

/*************************************************************************
  Which applications are Blocked the most
 
*************************************************************************/

SELECT BLOCKED_PROGRAM,
       COUNT(*) AS NUMBER
FROM   BLOCKS_VW
GROUP  BY BLOCKED_PROGRAM
ORDER  BY NUMBER DESC

/*************************************************************************
  Which applications are causing the most waiting
 
*************************************************************************/

SELECT BLOCKER_PROGRAM,
       SUM(WAIT_TIME) AS WAITTIME
FROM   BLOCKS_VW
GROUP  BY BLOCKER_PROGRAM
ORDER  BY WAITTIME DESC

/*************************************************************************
  Which applications are waiting the most
 
*************************************************************************/

SELECT BLOCKED_PROGRAM,
       SUM(WAIT_TIME) AS WAITTIME
FROM   BLOCKS_VW
GROUP  BY BLOCKED_PROGRAM
ORDER  BY WAITTIME DESC

/*************************************************************************
  Which objects are waiting the most
 
*************************************************************************/

SELECT OBJECT_NAME,
       SUM(WAIT_TIME) AS WAITTIME
FROM   BLOCKS_VW
GROUP  BY OBJECT_NAME
ORDER  BY WAITTIME DESC

/*************************************************************************
  Which databases are waiting the most
 
*************************************************************************/

SELECT DATABASE_NAME,
       SUM(WAIT_TIME) AS WAITTIME
FROM   BLOCKS_VW
GROUP  BY DATABASE_NAME
ORDER  BY WAITTIME DESC

 

Microsoft Dynamics AX general performance analysis scripts page 5

$
0
0

This is page 5 of 8 of the general performance analysis scripts online for the Performance Analyser 1.20 tool. See page 1 for the introduction. Use the links in the table below to navigate between pages.

- General analysis
Analyse SQL ConfigurationPage 1
Analyse SQL IndexesPage 2
Analyse SQL QueriesPage 3
Analyse BlockingPage 4
Baseline - benchmark queriesPage 5
- AX Specific
Analyse AX ConfigurationPage 6
Analyse AX IndexesPage 7
Analyse AX QueriesPage 8

Baseline - benchmark queries

INDEX_CHANGES_SINCE_BASELINE
QUERIES_SLOWER_THAN_BASELINE
QUERIES_FASTER_THAN_BASELINE
NEW_QUERIES_NOT_IN_BASELINE
QUERIES_IN_BASELINE_BUT_NOT_IN_CURRENT
TRANSACTION_VOLUME_BY_HOUR
TRANSACTION_VOLUME_BY_HOUR_DETAIL
DISK_IO_BY_HOUR
BAD_SQL_WAIT_STATS
DB_GROWTH
TABLE_ACTIVITY
ACTIVITY_COMPARISON_BETWEEN_RUNS

 

USE [DynamicsPerf]
GO
SELECT *
FROM   STATS_COLLECTION_SUMMARY
ORDER  BY STATS_TIME DESC

GO

----------------------------------------------------------------
--
--  INDEX_CHANGES_SINCE_BASELINE
--
--  show index changes from BASELINE
----------------------------------------------------------------

EXEC SP_INDEX_CHANGES
  @BASELINE = 'BASE_to_compare_to',
  @COMPARISON_RUN_NAME = 'Feb_26_2020_804AM'

----------------------------------------------------------------
--
--  QUERIES_SLOWER_THAN_BASELINE
--
--  queries that got worse  from BASELINE
----------------------------------------------------------------

SELECT A.QUERY_HASH,
       A.EXECUTION_COUNT,
       A.BEFORE_AVG_TIME,
       A.CURRENT_AVG_TIME,
       A.[TIME_DIFF(ms)],
       A.[%DECREASE],
       A.SQL_TEXT,
       B.QUERY_PLAN AS BEFORE_PLAN,
       C.QUERY_PLAN AS AFTER_PLAN
FROM   (SELECT DISTINCT V1.QUERY_HASH,
                        V1.EXECUTION_COUNT,
                        V1.AVG_ELAPSED_TIME                                                               AS BEFORE_AVG_TIME,
                        V2.AVG_ELAPSED_TIME                                                               AS CURRENT_AVG_TIME,
                        V2.AVG_ELAPSED_TIME - V1.AVG_ELAPSED_TIME                                         AS 'TIME_DIFF(ms)',
                        Cast(( V2.AVG_ELAPSED_TIME - V1.AVG_ELAPSED_TIME ) / CASE V1.AVG_ELAPSED_TIME
                                                                               WHEN 0 THEN 1
                                                                               ELSE V1.AVG_ELAPSED_TIME
                                                                             END * 100 AS DECIMAL(14, 3)) AS '%DECREASE',
                        V1.SQL_TEXT,
                        V1.QUERY_PLAN_HASH                                                                AS BEFORE_PLAN_HASH,
                        V2.QUERY_PLAN_HASH                                                                AS AFTER_PLAN_HASH
        FROM   QUERY_STATS_HASH_VW V1
               INNER JOIN QUERY_STATS_HASH_VW V2
                       ON V1.QUERY_HASH = V2.QUERY_HASH
        WHERE  V1.RUN_NAME = 'BASE_to_compare_to'
               AND V2.RUN_NAME = 'Feb_26_2020_804AM'
               AND V1.AVG_ELAPSED_TIME < V2.AVG_ELAPSED_TIME
               AND V1.QUERY_HASH <> 0x0000000000000000) AS A
       CROSS APPLY (SELECT TOP 1 QUERY_PLAN
                    FROM   QUERY_PLANS W1
                    WHERE  W1.QUERY_PLAN_HASH = A.BEFORE_PLAN_HASH) AS B
       CROSS APPLY (SELECT TOP 1 QUERY_PLAN
                    FROM   QUERY_PLANS W2
                    WHERE  W2.QUERY_PLAN_HASH = A.AFTER_PLAN_HASH) AS C
ORDER  BY 6 DESC

----------------------------------------------------------------
--
--  QUERIES_FASTER_THAN_BASELINE
--
--  queries that got faster from BASELINE
----------------------------------------------------------------

SELECT A.QUERY_HASH,
       A.EXECUTION_COUNT,
       A.BEFORE_AVG_TIME,
       A.CURRENT_AVG_TIME,
       A.[TIME_DIFF(ms)],
       A.[%IMPROVEMENT],
       A.SQL_TEXT,
       B.QUERY_PLAN AS BEFORE_PLAN,
       C.QUERY_PLAN AS AFTER_PLAN
FROM   (SELECT DISTINCT V1.QUERY_HASH,
                        V1.EXECUTION_COUNT,
                        V1.AVG_ELAPSED_TIME                                                               AS BEFORE_AVG_TIME,
                        V2.AVG_ELAPSED_TIME                                                               AS CURRENT_AVG_TIME,
                        V1.AVG_ELAPSED_TIME - V2.AVG_ELAPSED_TIME                                         AS 'TIME_DIFF(ms)',
                        Cast(( V1.AVG_ELAPSED_TIME - V2.AVG_ELAPSED_TIME ) / CASE V2.AVG_ELAPSED_TIME
                                                                               WHEN 0 THEN 1
                                                                               ELSE V2.AVG_ELAPSED_TIME
                                                                             END * 100 AS DECIMAL(14, 3)) AS '%IMPROVEMENT',
                        V1.SQL_TEXT,
                        V1.QUERY_PLAN_HASH                                                                AS BEFORE_PLAN_HASH,
                        V2.QUERY_PLAN_HASH                                                                AS AFTER_PLAN_HASH
        FROM   QUERY_STATS_HASH_VW V1
               INNER JOIN QUERY_STATS_HASH_VW V2
                       ON V1.QUERY_HASH = V2.QUERY_HASH
        WHERE  V1.RUN_NAME = 'BASE_to_compare_to'
               AND V2.RUN_NAME = 'Feb_26_2020_804AM'
               AND V1.AVG_ELAPSED_TIME > V2.AVG_ELAPSED_TIME
               AND V1.QUERY_HASH <> 0x0000000000000000) AS A
       CROSS APPLY (SELECT TOP 1 QUERY_PLAN
                    FROM   QUERY_PLANS W1
                    WHERE  W1.QUERY_PLAN_HASH = A.BEFORE_PLAN_HASH) AS B
       CROSS APPLY (SELECT TOP 1 QUERY_PLAN
                    FROM   QUERY_PLANS W2
                    WHERE  W2.QUERY_PLAN_HASH = A.AFTER_PLAN_HASH) AS C
ORDER  BY 6 DESC

 

----------------------------------------------------------------
--
--  NEW_QUERIES_NOT_IN_BASELINE
--
--  NEW queries that are not in the BASELINE
----------------------------------------------------------------

SELECT A.QUERY_HASH,
       A.BEFORE_AVG_TIME,
       A.SQL_TEXT,
       B.QUERY_PLAN AS BEFORE_PLAN
FROM   (SELECT DISTINCT V1.QUERY_HASH,
                        V1.AVG_ELAPSED_TIME AS BEFORE_AVG_TIME,
                        V1.SQL_TEXT,
                        V1.QUERY_PLAN_HASH  AS BEFORE_PLAN_HASH
        FROM   QUERY_STATS_HASH_VW V1
        WHERE  V1.RUN_NAME = 'Feb_26_2020_804AM'
               AND NOT EXISTS (SELECT QUERY_HASH
                               FROM   QUERY_STATS_HASH_VW V2
                               WHERE  V1.QUERY_HASH = V2.QUERY_HASH
                                      AND V2.RUN_NAME = 'BASE_to_compare_to')
               AND V1.QUERY_HASH <> 0x0000000000000000) AS A
       CROSS APPLY (SELECT TOP 1 QUERY_PLAN
                    FROM   QUERY_PLANS W1
                    WHERE  W1.QUERY_PLAN_HASH = A.BEFORE_PLAN_HASH) AS B
ORDER  BY 2 DESC

------------------------------------------------------------------------------
--
--  QUERIES_IN_BASELINE_BUT_NOT_IN_CURRENT
--
--   queries that were in the BASELINE but not in the comparison capture
-------------------------------------------------------------------------------

SELECT A.QUERY_HASH,
       A.BEFORE_AVG_TIME,
       A.SQL_TEXT,
       B.QUERY_PLAN AS BEFORE_PLAN
FROM   (SELECT DISTINCT V1.QUERY_HASH,
                        V1.AVG_ELAPSED_TIME AS BEFORE_AVG_TIME,
                        V1.SQL_TEXT,
                        V1.QUERY_PLAN_HASH  AS BEFORE_PLAN_HASH
        FROM   QUERY_STATS_HASH_VW V1
        WHERE  V1.RUN_NAME = 'BASE_to_compare_to'
               AND NOT EXISTS (SELECT QUERY_HASH
                               FROM   QUERY_STATS_HASH_VW V2
                               WHERE  V1.QUERY_HASH = V2.QUERY_HASH
                                      AND V2.RUN_NAME = 'Feb_26_2020_804AM')
               AND V1.QUERY_HASH <> 0x0000000000000000) AS A
       CROSS APPLY (SELECT TOP 1 QUERY_PLAN
                    FROM   QUERY_PLANS W1
                    WHERE  W1.QUERY_PLAN_HASH = A.BEFORE_PLAN_HASH) AS B
ORDER  BY 2 DESC

 

----------------------------------------------------------------
--
--  TRANSACTION_VOLUME_BY_HOUR
--
--  Show change in row counts by hour
----------------------------------------------------------------

USE [DynamicsPerf]

--Hourly Totals
SELECT *
FROM   PERF_HOURLY_ROWDATA_VW
WHERE  ROWRANK = 9999
       AND DATABASE_NAME <> 'NULL'
ORDER  BY STATS_TIME DESC

----------------------------------------------------------------
--
--  TRANSACTION_VOLUME_BY_HOUR_DETAIL
--
--  Show details of change in row counts by hour
----------------------------------------------------------------

SELECT *
FROM   PERF_HOURLY_ROWDATA_VW
WHERE  STATS_TIME = 'ENTER_STATS_TIME_HERE_FROM_PREVIOUS_QUERY'
       AND TABLE_NAME <> 'NULL'
ORDER  BY ROWRANK

----------------------------------------------------------------
--
--  DISK_IO_BY_HOUR
--
--  Hourly Change in Disk IO Stats by File
----------------------------------------------------------------

SELECT *
FROM   PERF_HOURLY_IOSTATS_VW
WHERE DATABASE_NAME= 'Dynamics'
ORDER BY STATS_TIME DESC, DATABASE_NAME, FILE_ID

----------------------------------------------------------------
--
--  BAD_SQL_WAIT_STATS
--
-- IO bottleneck : If Top 2 values for wait stats include IO, (ASYNCH_IO_COMPLETION,IO_COMPLETION,LOGMGR,,WRITELOG,PAGEIOLATCH_x_xxx) there is an IO bottleneck.
-- Blocking bottleneck: If top 2 wait_stats values include locking (LCK_M_BU, LCK_M_IS, LCK_M_IU, LCK_% …), there is a blocking bottleneck
-- Parallelism: Cxpacket waits > 5%
----------------------------------------------------------------

/*********************************************************************************************

************************************************************************************************/

SELECT STATS_TIME,
       RANK,
       WAIT_TYPE,
       WAITING_TASKS_LAST_HOUR,
       WAIT_TIME_MS_LAST_HOUR
FROM   PERF_HOURLY_WAITSTATS_VW
WHERE  ( WAIT_TYPE LIKE 'PAGEIOLATCH_%'
          OR WAIT_TYPE LIKE 'ASYNCH_IO_COMPLETION%'
          OR WAIT_TYPE LIKE 'IO_COMPLETION%'
          OR WAIT_TYPE LIKE 'LOGMGR%'
          OR WAIT_TYPE LIKE 'WRITELOG%' )
       AND RANK < 3
       AND WAIT_TIME_MS_LAST_HOUR > 0

 

 

--Activity between 2 data collections to look at comparisons over a longer time period
--Find all run_names

SELECT RUN_NAME
FROM   STATS_COLLECTION_SUMMARY
ORDER  BY STATS_TIME DESC

----------------------------------------------------------------
--
--  DB_GROWTH
--

--Find record count and table size differences between the runs
--Can use this to accurately predict database growth
--NOTE only TOP 1000 tables are returned
--------------------------------------------------------------------------------
SELECT *
FROM   fn_dbstats('STARTING_RUN_NAME', 'ENDING_RUN_NAME')
ORDER  BY DELTA_SIZEMB DESC

 

----------------------------------------------------------------
--
--  TABLE_ACTIVITY
--

--Find record read/write and row count differences between the runs
-------------------------------------------------------------------

SELECT A.TABLE_NAME,
       B.ROW_COUNT - A.ROW_COUNT                       AS DELTA_IN_ROWS,
       B.TOTALREADOPERATIONS - A.TOTALREADOPERATIONS   AS DELTA_IN_READS,
       B.TOTALWRITEOPERATIONS - A.TOTALWRITEOPERATIONS AS DELTA_IN_WRITES
FROM   INDEX_OPS_VW A
       INNER JOIN INDEX_OPS_VW B
               ON A.TABLE_NAME = B.TABLE_NAME
                  AND A.DATABASE_NAME = B.DATABASE_NAME
                  AND A.RUN_NAME = 'STARTING_RUN_NAME'
                  AND B.RUN_NAME = 'ENDING_RUN_NAME'
ORDER  BY 2 DESC

----------------------------------------------------------------
--
--  SQL_WAIT_STATS_BY_HOUR
--- Hourly Change in SQL Server Wait Stats
----------------------------------------------------------------

SELECT *
FROM   PERF_HOURLY_WAITSTATS_VW
ORDER BY STATS_TIME DESC, RANK

 

----------------------------------------------------------------
--
--  ACTIVITY_COMPARISON_BETWEEN_RUNS
--
--
--  Comparison queries between different data captures
-----------------------------------------------------------------

SELECT D1.RUN_NAME           AS RUN1,
       D2.RUN_NAME           AS RUN2,
       D1.SQL_TEXT,
       D1.QUERY_PLAN,
       D1.AVG_ELAPSED_TIME   AS RUN1_AVG_TIME,
       D2.AVG_ELAPSED_TIME   AS RUN2_AVG_TIME,
       D2.AVG_ELAPSED_TIME-D1.AVG_ELAPSED_TIME AS TIME_DIFF,
       D1.AVG_LOGICAL_READS  AS RUN1_READS,
       D2.AVG_LOGICAL_READS  AS RUN2_READS,
       D2.AVG_LOGICAL_READS-D1.AVG_LOGICAL_READS AS READS_DIFF,
       D1.AVG_LOGICAL_WRITES AS RUN1_WRITES,
       D2.AVG_LOGICAL_WRITES AS RUN2_WRITES,
       D2.AVG_LOGICAL_WRITES-D1.AVG_LOGICAL_WRITES AS WRITES_DIFF,
       D1.QUERY_HASH
FROM   QUERY_STATS_VW D1
       INNER JOIN QUERY_STATS_VW D2
         ON D1.QUERY_HASH = D2.QUERY_HASH
        AND D1.DATABASE_NAME = D2.DATABASE_NAME
WHERE  D1.QUERY_HASH <> 0x0000000000000000
       AND D1.RUN_NAME = 'STARTING_RUN_NAME'
       AND D2.RUN_NAME = 'ENDING_RUN_NAME'
ORDER  BY D2.AVG_ELAPSED_TIME - D1.AVG_ELAPSED_TIME

 

 

 

Microsoft Dynamics AX general performance analysis scripts page 6

$
0
0

This is page 6 of 8 of the general performance analysis scripts online for the Performance Analyser 1.20 tool. See page 1 for the introduction. Use the links in the table below to navigate between pages.

- General analysis
Analyse SQL ConfigurationPage 1
Analyse SQL IndexesPage 2
Analyse SQL QueriesPage 3
Analyse BlockingPage 4
Baseline - benchmark queriesPage 5
- AX Specific
Analyse AX ConfigurationPage 6
Analyse AX IndexesPage 7
Analyse AX QueriesPage 8

Analyse AX Configuration

AOS_DEBUG
CONNECTION_CONTEXT
TOO_BIG_FOR_ENTIRE_TABLE_CACHE
TABLES_THAT_COULD_BE_ENTIRE_TABLE_CACHE
ENTIRE_TABLE_CACHE_WITH_UPDATES
OCC_DISABLED
AX_DATABASE_LOGGING
AX_ALERTS_ON_TABLE
AX_BATCH_CONFIGURATION
AOS_CLUSTER_CONFIG
AX_DB_LOGGING_BY_TABLE
NUMBER_SEQUENCE_USAGE

 

USE DynamicsPerf

--AOS Configuration issues
--
--    AOS_DEBUG
  -- --------------------------------------------------------------
  -- Is Enable X++ Debug enabled on any AOS Servers.
  -- 20% decline in transactions processed on the AOS instances with this enabled
  -----------------------------------------------------------------
  
  SELECT SERVER_NAME,
      AOS_INSTANCE_NAME,
      SETTING_NAME,
      SETTING_VALUE
  FROM   AOS_REGISTRY
  WHERE  IS_CONFIGURATION_ACTIVE = 'Y'
      AND SETTING_NAME = 'xppdebug'
      AND SETTING_VALUE <> '0'

  -- --------------------------------------------------------------
  --    CONNECTION_CONTEXT
  -- Is Context_Info enabled on any AOS Servers.
  --
  -----------------------------------------------------------------
  
  SELECT SERVER_NAME,
      AOS_INSTANCE_NAME,
      SETTING_NAME,
      SETTING_VALUE
  FROM   AOS_REGISTRY
  WHERE  IS_CONFIGURATION_ACTIVE = 'Y'
      AND SETTING_NAME = 'connectioncontext'
      AND SETTING_VALUE <> '0'

 

--AOT configuration issues
  
   --  TOO_BIG_FOR_ENTIRE_TABLE_CACHE

   -- --------------------------------------------------------------
   -- Find tables that have entire table cache enabled that are larger than 128K
   -- Causes the cache to overflow to disk on the AOS Server
   -----------------------------------------------------------------

   SELECT A.TABLE_NAME,
       APPLICATION_LAYER,
       CACHE_LOOKUP,
       PAGE_COUNT
   FROM   AX_TABLE_DETAIL_CURR_VW A,
       INDEX_STATS_CURR_VW I
   WHERE  A.DATABASE_NAME = I.DATABASE_NAME
       AND A.TABLE_NAME = I.TABLE_NAME
       AND CACHE_LOOKUP = 'EntireTable'
       AND ( INDEX_DESCRIPTION = 'HEAP'
        OR INDEX_DESCRIPTION LIKE 'CLUSTERED%' )
       AND PAGE_COUNT > 16  -- 128kb
       --AND PAGE_COUNT> 4  --32KB AX2012RTM
       --AND PAGE_COUNT> 12  --96KB AX2012R2
      
   ORDER  BY PAGE_COUNT DESC

   --  TABLES_THAT_COULD_BE_ENTIRE_TABLE_CACHE

   -- --------------------------------------------------------------
   -- Find tables that have no cache enabled that are smaller than 128K
   -- These could cause lots of roundtrips between AOS and SQL
   --
   -- NOTE:
   -- Table should be static and not updated much before changing
   -- cache to Entiretable
   -----------------------------------------------------------------

   SELECT A.TABLE_NAME,
       APPLICATION_LAYER,
       CACHE_LOOKUP,
       PAGE_COUNT
   FROM   AX_TABLE_DETAIL_CURR_VW A,
       INDEX_STATS_CURR_VW I
   WHERE  A.DATABASE_NAME = I.DATABASE_NAME
       AND A.TABLE_NAME = I.TABLE_NAME
       AND CACHE_LOOKUP = 'None'
       AND ( INDEX_DESCRIPTION = 'HEAP'
        OR INDEX_DESCRIPTION LIKE 'CLUSTERED%' )
       AND PAGE_COUNT < 16  -- 128kb
       --AND PAGE_COUNT> 4  --32KB AX2012RTM
       --AND PAGE_COUNT> 12  --96KB AX2012R2
       AND PAGE_COUNT > 0
      
   ORDER  BY TABLE_NAME DESC
   --
   --  ENTIRE_TABLE_CACHE_WITH_UPDATES
   --
   -- --------------------------------------------------------------
   -- Find tables that have entire table cache and show update rate
   -- Causes the cache to be refreshed on all AOS instances
   -----------------------------------------------------------------
   
   SELECT A.TABLE_NAME,
       APPLICATION_LAYER,
       CACHE_LOOKUP,
       USER_UPDATES
   FROM   AX_TABLE_DETAIL_CURR_VW A,
       INDEX_STATS_CURR_VW I
   WHERE  A.DATABASE_NAME = I.DATABASE_NAME
       AND A.TABLE_NAME = I.TABLE_NAME
       AND CACHE_LOOKUP = 'EntireTable'
       AND ( INDEX_DESCRIPTION = 'HEAP'
        OR INDEX_DESCRIPTION LIKE 'CLUSTERED%' )
   ORDER  BY USER_UPDATES DESC

   --
   -- OCC_DISABLED
   --
   -- --------------------------------------------------------------
   --  Find tables above SYS layer that do not have OCC enabled:
   --
   -----------------------------------------------------------------
   
   SELECT TABLE_NAME
   FROM   AX_TABLE_DETAIL_CURR_VW
   WHERE  APPLICATION_LAYER NOT IN ( 'SYS', 'System Table' )
       AND OCC_ENABLED = 0
   ORDER  BY TABLE_NAME

   --
   -- AX_DATABASE_LOGGING
   --
   -- --------------------------------------------------------------
   -- Find tables above SYS layer that have logging enabled
   --
   -----------------------------------------------------------------
   
   SELECT *
   FROM   AX_TABLE_DETAIL_CURR_VW
   WHERE  APPLICATION_LAYER NOT IN ( 'SYS', 'System Table' )
       AND ( DATABASELOG_INSERT = 1
        OR DATABASELOG_DELETE = 1
        OR DATABASELOG_UPDATE = 1
        OR DATABASELOG_RENAME_KEY = 1 )
   ORDER  BY TABLE_NAME

   --
   --  AX_ALERTS_ON_TABLE
   --
   -- --------------------------------------------------------------
   -- Find tables above SYS layer that have events enabled
   --
   -----------------------------------------------------------------
   
   SELECT *
   FROM   AX_TABLE_DETAIL_CURR_VW
   WHERE  APPLICATION_LAYER NOT IN ( 'SYS', 'System Table' )
       AND ( EVENT_INSERT = 1
        OR EVENT_DELETE = 1
        OR EVENT_UPDATE = 1
        OR EVENT_RENAME_KEY = 1 )
   ORDER  BY TABLE_NAME

   -- SELECT * FROM EVENTRULE   -- DO THIS IN THE AX DATABASE TO DISCOVER ABOVE DATA

--AX Application configuration issues

   --
   --  AX_BATCH_CONFIGURATION
   --
   -- -----------------------------------------------------------------------------
   -- List BATCHGROUP configuration in Dynamics AX
   --------------------------------------------------------------------------------
   
   SELECT *
   FROM   AX_BATCH_CONFIGURATION_VW

   --
   --  AOS_CLUSTER_CONFIG
   --
   -- -----------------------------------------------------------------------------
   -- List AOS cluster configuration in Dynamics AX
   --------------------------------------------------------------------------------

   SELECT *
   FROM   AX_SERVER_CONFIGURATION_VW

   --
   --  AX_DB_LOGGING_BY_TABLE
   --
   -- --------------------------------------------------------------
   -- List top 200 tables be logged in Dynamics AX
   -- NOTE: if this query returns zero rows
   --         the AOTEXPORT class has not been run
   -----------------------------------------------------------------

   SELECT [TABLE_NAME],
       [ROWS_LOGGED],
       [DATABASELOG_UPDATE],
       [DATABASELOG_DELETE],
       [DATABASELOG_INSERT]
   FROM   [AX_DATABASELOGGING_VW]
   ORDER  BY [ROWS_LOGGED] DESC
   
   --
   --  NUMBER_SEQUENCE_USAGE
   --
   -- -----------------------------------------------------------------------------
   -- List NUMBERSEQUENCE table configuration in Dynamics AX
   -- Are sequences marked as Coninuous?  If so why?
   -- Is FETCHAHEADQTY > 0,  if not preallocation is not setup for this sequence
   -- Pre-allocation requires knowledge of the avg. number of numbers consumed
   -- per user process to determine a good value.       
   --------------------------------------------------------------------------------
   
   SELECT RUN2.[DATABASE_NAME],
       RUN2.[COMPANYID],
       RUN2.[NUMBERSEQUENCE],
       RUN2.[TEXT],
       Datediff(hh, RUN1.STATS_TIME, RUN2.STATS_TIME)                                       AS ELAPSED_HOURS,
       RUN2.NEXTREC - RUN1.NEXTREC                                                          AS TOTAL_NUMBERS_CONSUMED,
       ( RUN2.NEXTREC - RUN1.NEXTREC ) / ( Datediff(hh, RUN1.STATS_TIME, RUN2.STATS_TIME) ) AS HOURLY_CONSUMPTION_RATE,
       RUN2.HIGHEST - RUN2.NEXTREC                                                          AS [NUMBERSREMAINING],
       RUN2.[CONTINUOUS],
       RUN2.[FETCHAHEAD],
       RUN2.[FETCHAHEADQTY]
   FROM   AX_NUM_SEQUENCES_VW RUN1
       INNER JOIN AX_NUM_SEQUENCES_VW RUN2
         ON RUN1.NUMBERSEQUENCE = RUN2.NUMBERSEQUENCE
         AND RUN1.COMPANYID = RUN2.COMPANYID
   WHERE  RUN1.RUN_NAME = 'BASE_to_compare_to'
       AND RUN2.RUN_NAME = 'Feb_26_2020_804AM'
   ORDER  BY 6 DESC

 

   --To find run_name run the following query

   SELECT *
   FROM   STATS_COLLECTION_SUMMARY
   ORDER  BY STATS_TIME DESC

   -- --------------------------------------------------------------
   -- Review number sequence configuration in Dynamics AX
   -----------------------------------------------------------------

   SELECT *
   FROM   AX_NUM_SEQUENCES_CURR_VW
   WHERE  CONTINUOUS = 'Yes'

 

Microsoft Dynamics AX general performance analysis scripts page 7

$
0
0

This is page 7 of 8 of the general performance analysis scripts online for the Performance Analyser 1.20 tool. See page 1 for the introduction. Use the links in the table below to navigate between pages.

- General analysis
Analyse SQL ConfigurationPage 1
Analyse SQL IndexesPage 2
Analyse SQL QueriesPage 3
Analyse BlockingPage 4
Baseline - benchmark queriesPage 5
- AX Specific
Analyse AX ConfigurationPage 6
Analyse AX IndexesPage 7
Analyse AX QueriesPage 8

Analyse AX Indexes

INDEXES_IN_DB_NOT_IN_AOT
INDEXES_WITH_RECVERSION 

--
--   INDEXES_IN_DB_NOT_IN_AOT
--
-- --------------------------------------------------------------
-- Find INDEXES that are not defined in the AOT
--
-----------------------------------------------------------------

SELECT *
FROM   INDEX_STATS_CURR_VW I
WHERE  INDEX_DESCRIPTION <> 'HEAP' AND INDEX_DESCRIPTION NOT LIKE '%FILTERED%'
       AND NOT EXISTS (SELECT *
                       FROM   AX_INDEX_DETAIL_CURR_VW A
                       WHERE  A.DATABASE_NAME = I.DATABASE_NAME
                              AND A.TABLE_NAME = I.TABLE_NAME
                              AND A.INDEX_NAME = I.INDEX_NAME)
ORDER  BY TABLE_NAME,
          INDEX_NAME

--
--   INDEXES_WITH_RECVERSION
--
-- --------------------------------------------------------------
-- Find INDEXES that have RECVERSION in the Key or Included list
--  RECVERSION should NOT be apart of AX Indexes do to the
--  frequency of updates
-----------------------------------------------------------------

SELECT *
FROM   INDEX_STATS_CURR_VW I
WHERE  INDEX_KEYS LIKE '%RECVERSION%'
        OR INCLUDED_COLUMNS LIKE '%RECVERSION%'
ORDER  BY TABLE_NAME,
          INDEX_NAME

 

 

 

.

Microsoft Dynamics AX general performance analysis scripts page 8

$
0
0

This is page 8 of 8 of the general performance analysis scripts online for the Performance Analyser 1.20 tool. See page 1 for the introduction. Use the links in the table below to navigate between pages.

- General analysis
Analyse SQL ConfigurationPage 1
Analyse SQL IndexesPage 2
Analyse SQL QueriesPage 3
Analyse BlockingPage 4
Baseline - benchmark queriesPage 5
- AX Specific
Analyse AX ConfigurationPage 6
Analyse AX IndexesPage 7
Analyse AX QueriesPage 8

Analyse AX Queries

AX_LONG_RUNNING_QUERY_TRACE
HIDDEN_SCANS_QUERIES
OPTION_FAST_QUERIES
USER_SCANS_QUERY

--
--   AX_LONG_RUNNING_QUERY_TRACE
--
-- --------------------------------------------------------------
-- Find long running queries from Dynamics AX with source code
-- requires client tracing being enabled on the AOS configuration
----------------------------------------------------------------

SELECT TOP 100 [CREATED_DATETIME],[DATABASE_NAME],[ROW_NUM], [AX_USER_ID], [SQL_DURATION], [SQL_TEXT], [CALL_STACK], [TRACE_CATEGORY], [TRACE_EVENT_CODE], [TRACE_EVENT_DESC], [TRACE_EVENT_DETAILS], [CONNECTION_TYPE], [SQL_SESSION_ID], [AX_CONNECTION_ID], [IS_LOBS_INCLUDED], [IS_MORE_DATA_PENDING], [ROWS_AFFECTED], [ROW_SIZE], [ROWS_PER_FETCH], [IS_SELECTED_FOR_UPDATE], [IS_STARTED_WITHIN_TRANSACTION], [SQL_TYPE], [STATEMENT_ID], [STATEMENT_REUSE_COUNT], [DETAIL_TYPE], [STATS_TIME], [COMMENT]
FROM   [AX_SQLTRACE]
ORDER  BY [CREATED_DATETIME] DESC

--
--  HIDDEN_SCANS_QUERIES
--
-- --------------------------------------------------------------
-- Find Dynamics AX queries that only seek on DataAreaId
-- NOT USEFUL for other products
-----------------------------------------------------------------

SELECT TOP 100 *
FROM   HIDDEN_SCANS_CURR_VW
ORDER  BY TOTAL_ELAPSED_TIME DESC

--
--  OPTION_FAST_QUERIES
--
-------------------------------------------------------------------------
-- Find queries option(fast) set that have sort operations
--  Dynamics AX only query
--
-- Either we don't have an index to match the order by clause
--  or the query is potentially to complex for SQL to pick that index
--------------------------------------------------------------------------

SELECT TOP 100 *
FROM   QUERY_STATS_CURR_VW
WHERE  SQL_TEXT LIKE '%OPTION(FAST%'
       AND QUERY_PLAN_TEXT LIKE '%PhysicalOp="Sort"%'
ORDER  BY TOTAL_ELAPSED_TIME DESC

--
--  USER_SCANS_QUERY
--
-- --------------------------------------------------------------
-- Find Dynamics queries that are scanning
-----------------------------------------------------------------

SELECT TOP 100 *
FROM   USER_SCANS_CURR_VW
ORDER  BY TOTAL_ELAPSED_TIME DESC

 

AX Content: Working together on Labor Day

$
0
0

Permit us once more to vary from the technical nature of our weekly posts. In keeping with an approach we've taken over the past eight or nine month in the articles we post close to holidays, we're pausing to think about what we're doing, check our own goals and invite your response to the thinking that's behind our actions.

So as I thought about this post on the Labor Day holiday in the United States, it occurs to me that this is something of a "free" holiday for many of us. There's generally no particular shopping or gift-giving required, and no elaborate meals or special rituals that we observe, although some people certainly do one or more of each of those activities.

If anything, I wonder if there might be a sense of hesitation, almost ambivalence about this day. Labor Day is a day set aside to honor members of the organized labor movement who struggled for better, safer, more humane working conditions for the people we refer to as "blue collar" workers. If that movement has fallen out of favor with some, it’s not my task here to argue for or against any side of that debate. Rather than staking out a debate position, I'll use the annual commemoration of progress through conflict to make a statement of the obvious and then offer a brief comment on it.

Any genuine conflict – whether between workers and managers, between co-workers, or between a business and its customers – indicates the vulnerability of our relationships. There are myriad reasons for the fragility of our relationships and for our purposes here those reasons don't really matter. But where there's real conflict – not a difference of opinion or a struggle between competing priorities but conflict that breeds enmity – there lies beneath, a damaged or broken relationship.

As I draft this blog post in mid-August 2014 the news seems flooded by this brokenness: in Gaza, in the Ukraine, in Ferguson, Missouri in the United States to cite a few glaring, painful examples. It’s nowhere close to a complete list. Of course, an obvious rejoinder to that statement is that relationships can also be resilient. People who've endured awful suffering from terribly damaged relationships can rebound, recover, and ultimately heal. There's hope in that and a reason to keep working. 

But if relationships are more important to workplace success than software, then where does that leave those of us who are brought together through the work of creating and delivering software? We can't provide or deliver or fix relationships in our products, whatever advertising tries to promise. Relationships have to be through care and time and nurturing.

Instead, we try to provide tools that facilitate specific work that needs to be done, and if we’re successful, those tools become invisible as our customers gain competence in using them to complete their work.  If that sounds so simple that it's not worth blogging about, I submit that most of our software tools are "in our faces" a bit too much. They can be more noticeable than they should be because of design flaws or because they contain needed complexity that's challenging to install, configure and use.

Our work is to try to make all of that better. On Tuesday after the Labor Day holiday, as you go about your work, I invite you to let us know where we're getting it right and where something needs to be fixed. I invite you to a relationship that's open to confronting what doesn't work, willing to acknowledge what does work, and that thrives within the vulnerability that comes from recognizing that what we're trying hard to do might fail. And then committing to the resilience to make it better for both of us. For all of us. 

Have a great Labor Day!

Enabling the new Call Center Channel User Functionality in AX 2012 R3

$
0
0

The release of AX 2012 R3 added a new Call Center module which utilizes Channel Users.  These users are set up in the Call Center Channel in the Retail module (Retail >> Common >> Retail channels >> Call centers).  The purpose of these specified users is to enable certain feature sets within the sales orders form that enable functionality such as ordering from catalogs and extending customer payment options.  If a user is not listed in the Channel User list, they can still access the Call Center module, but the additional sales order functionality will not be available when creating new sales orders.  It is important to note that a non-channel user can access a sales order created by a channel user and be able to see those extra options.  Whether or not the extra call center functionality exists depend on the user creating the sales order.


Channel users
To access this list go to: Retail >> Common >> Retail channels >> Call centers >> Channel users


The channel user list is a simple list comprised of users who would have access to certain call center features (discussed in the next section below) on the sales order form.  If a user is on this list, and when they create a sales order from any module, they will receive the extra functionality associated to the Call Center Channel.




Call center channel
There are 3 options in the Call Center form that enable the feature sets in the Sales Order form.  Each one of these is described below and can also be found in the TechNet article linked below.

Set up a call center
http://technet.microsoft.com/EN-US/library/dn497725.aspx

Enable order completion
Select this check box to enable the following features for call center users in the Sales order form:
     ◦ The payment process – Multiple payment buttons in the Sales order form are enabled when the Enable order completion check box is selected.
     ◦ The Complete button – This button controls access to the Sales order summary form, where the user can enter payment and submit the order. If the Enable order completion check box is not selected, users can create and save orders, but cannot complete them. 
     ◦ The Recap button – This button controls access to the Sales order summary form, where the user can review the order, and optionally enter payment and submit the order.
     ◦ The Coupons button – Coupon calculation requires that the order be completed. 

Enable directed selling
Select this check box to enable the following directed selling options for call center users in the Sales order form:
     ◦ Source codes
     ◦ Scripts
     ◦ Additional item information
     ◦ Catalog requests

Enable order price control 
Select this check box to enable the following price control options for call center users in the Sales order form:
     ◦ Price matching
     ◦ Price details
     ◦ Price overrides
     ◦ Margin alerts

Here is a view of the Call Center form with the 3 Call Center options marked that will enable these features.




Sales orders

When these features are selected and a Call center channel user creates a sales order, the sales order form will display different buttons and fields as seen below with a few highlights of the newly available options:



A non-call center channel user would see the following:



 

 


AX Performance Troubleshooting Checklist Part 1B [Application and AOS Configuration]

$
0
0

This is the second page of Part 1, in a two part troubleshooting check list for general performance on Microsoft Dynamics AX. This page (Part 1B) covers  AX application and AOS configuration settings.

Please see the previous page for the introduction and Part 1A of the check list, which covers SQL Server and Storage Settings. Part 2 (following on later) will cover hardware, indexing, queries,  blocking and code (at a high level).

Below there is also a link to a script you can use to gather some of the required information from your system. It requires the Performance Analyser 1.20 to be installed first.

Part 1B: AX application and AOS configuration settings

Analysis script: http://blogs.msdn.com/b/axsupport/archive/2014/09/01/microsoft-dynamics-ax-general-performance-analysis-scripts-page-6.aspx

Some settings can be checked manually in the application (steps given in the links below) or AX Server Configuration Utility (Start> Administrative Tools> Microsoft Dynamics AX Server Configuration).

Application settings

Kernel & Application Builds

Recommendation
-Generally we recommend a recent kernel build and the highest possible application build, in order to get the benefit of the latest hot fixes. For example, on support we have seen a number of AX 2012 (RTM and R2) customers with performance issues benefiting from installing CU7 (kernel and application).
-Have a regular patching strategy in place.
 
How to...
 
Overview of Microsoft Dynamics AX build numbers: http://blogs.msdn.com/b/axsupport/archive/2012/03/29/overview-of-ax-build-numbers.aspx
 
Patching Strategy for Dynamics AX: http://blogs.msdn.com/b/axinthefield/archive/2014/08/22/patching-strategy-for-dynamics-ax.aspx

Number sequences:

Recommendation:
-For each number sequence, unless there is a regulatory requirement that you use continuous, we recommend that you use non-continuous for better performance*
-Where number sequences absolutely must be continuous, carefully consider server usage when you plan the cleanup process. We recommend that you perform the cleanup as a batch job during non-peak hours.*
-Use pre-allocation for non continuous number sequences**

*Further details: Number sequence overview [AX 2012]
**Explanation: http://blogs.msdn.com/b/axinthefield/archive/2011/05/02/how-preallocated-number-sequences-are-cached-in-ax.aspx

How to...

Number sequences (form) [AX 2012]:
http://technet.microsoft.com/EN-US/library/hh209531.aspx

AX 2009: "Introduction to AX 2009" training materials on Partnersource or Customersource, e.g. https://mbs.microsoft.com/customersource/Global/AX/learning/student-training-materials/course80020(Chapter 5)

Determining what pre-allocation to set: use the script provided in Performance Analyser 1.20, in the folder: Analyze AX Configuration, "Analyze AX Configuration", section "NUMBER_SEQUENCE_USAGE"

Database logging and alerts:

Recommendation:
-Only use these when absolutely necessary. Certainly don't enable it on transactional tables. See:
http://blogs.msdn.com/b/axinthefield/archive/2011/06/12/too-much-database-logging-in-dynamics-ax.aspx
(similar principle applies to alerts)
 
How to...

Configure and manage database logging [AX 2012]:
http://technet.microsoft.com/en-us/library/dd362089.aspx

AX 2009: "Administration in Microsoft Dynamics AX 2009" training materials on Partnersource or Customersource, e.g.
   https://mbs.microsoft.com/customersource/Global/AX/learning/student-training-materials/courseAX2009ADM (Chapter 6 - alerts)

Extensible Data Security (XDS) / Record Level Security (RLS):
[RLS will be removed in a future version]

Recommendation:
-Exercise caution with the queries used, for example: validate that ranges are not using wildcards at the start of the criteria (*xxxx), as this can result in index scans in SQL; keep the queries as simple as possible. Also be aware record level security can affect set based operations: http://blogs.msdn.com/b/daxis/archive/2009/01/11/what-s-new-in-set-based-operations-in-dynamics-ax-2009.aspx
 
How to...

Developing Extensible Data Security Policies (White paper) [AX 2012]
http://technet.microsoft.com/en-us/library/hh272862.aspx

Manage record level security [AX 2012]
http://technet.microsoft.com/en-us/library/aa570084.aspx

Manage record-level security [AX 4.0 & 2009]:
http://www.microsoft.com/en-us/download/details.aspx?id=10680

Configuration Keys:
-Turn off 'keep update objects' configuration key for new installations.

 http://blogs.msdn.com/b/axsupport/archive/2012/04/19/turn-off-keep-update-objects-in-ax-2012-for-new-installations.aspx

http://blogs.msdn.com/b/emeadaxsupport/archive/2008/11/03/performance-sysdeletedobjects40-keep-updated-objects.aspx

-Turn off any other configuration keys which are not required (for similar reasons to those above and it is also potentially skipping additional logic in the code which is not required).

How to...

Configure application functionality [AX 2012]:
http://technet.microsoft.com/EN-US/library/aa496468.aspx

AX 2009: "Administration in Microsoft Dynamics AX 2009" training materials on Partnersource or Customersource, e.g.        https://mbs.microsoft.com/customersource/Global/AX/learning/student-training-materials/courseAX2009ADM(Chapter 1)

Memo fields

Recommendation:
-Review the use of memo and container fields in application tables.
Best Practices: Table Fields [AX 2012]
 
How to...
Performance - memo/ntext fields:
   http://blogs.msdn.com/b/emeadaxsupport/archive/2008/11/03/performance-memo-ntext-fields.aspx

Entire table caching:

Recommendation:
-Avoid using EntireTable caches for large tables (in AX 2009 over 128 KB or 16 pages, in AX 2012 over 'entire table cache size' application setting [default: 32KB, or 4 pages]) - move to record caching instead.
-Avoid using EntireTable caches for highly updated tables - move to record caching instead.
-Candidates for EntireTable cache - static tables (e.g. parameter tables) that have no cache enabled and are smaller than 128K (16 pages) [AX 2009] or smaller than the entire table cache size application setting (default=32KB or 4 pages) [AX 2012].
-Set-based Caching [AX 2012]
 
How to...

Table properties:
http://msdn.microsoft.com/en-us/library/aa871620.aspx

Best practices for table properties:
http://msdn.microsoft.com/en-us/library/aa632254.aspx

AX 2012 entire table cache size setting:
http://msdn.microsoft.com/EN-US/library/bb314693.aspx
(section: 'configuring the cache sizes')

Record caching

Recommendation:
-Ensure there is an appropriate unique index (AX 2012) or primary key (AX 2009) to support record caching for frequently executed queries on each table.
-Check for custom tables where the 'table group' property is 'none' and the cache lookup property is 'miscellaneous'. This can often indicate that caching hasn't been considered, because these are default values.
-Single-record Caching [AX 2012]
 
How to...

As a rough guide (at your own risk, bearing in mind there can be exceptions including the above EntireTable best practices), you can use the following approach:

  1. Set TableGroup property according to how it is used (following advice in the references below).
  2. Set the CacheLookup property based on TableGroup (some table groups only applicable to AX 2012; see above links): Parameter = EntireTable, Group / Reference / Main = Found, Transaction/Transaction header/Transaction line/Worksheet/Worksheet header/Worksheet line = NotInTTS

[AX 2012 only]
Client performance options:

Recommendation:
-Part 1 - Review set up as per the blog (see right).
-Bear in mind development guidance in the blog for code review (check list part 2).
 
How to...
Microsoft Dynamics AX 2012: Client Performance Options:
http://blogs.msdn.com/b/axperf/archive/2011/11/07/ax2012-client-performance-options.aspx

[AX 2012 only]
Server Configuration - Performance Optimization:

Recommendation:
-Generally we recommend to keep the defaults - establish the reasons behind any changes from the defaults.
 
How to...
Server configuration (form) [AX 2012]:
http://technet.microsoft.com/en-us/library/hh208825.aspx

Server Configuration - Batch server schedule:

Recommendation:
-Max threads can vary widely depending on the workload. http://blogs.msdn.com/b/axinthefield/archive/2011/03/25/optimizing-ax-batch-performance-using-batch-group-configurations.aspx
-Schedule can be used to define a window when batch processing occurs, to avoid / reduce impact on other processes.
 
How to...
Server configuration (form) [AX 2012]:
http://technet.microsoft.com/en-us/library/hh208825.aspx

AX 2009:Administration > Setup > System > Server configuration

OCC Enabled

Recommendation:
-Default (recommended)='Yes'. Specifies whether the optimistic concurrency mode is enabled for a table. When this mode is enabled, data is not locked from future modification when it is fetched from the database. Data is locked only when the actual update is performed.
 
How to...
Server configuration (form) [AX 2012]:
http://technet.microsoft.com/en-us/library/hh208825.aspx

AOS Configuration settings

Overview:

Recommendation:
-Generally we recommend to keep the defaults in your production environment; establish the reasons behind any changes from the defaults.
 
How to...

Manage an AOS configuration:
http://technet.microsoft.com/en-us/library/aa569618.aspx

Application Object Server options:
http://technet.microsoft.com/EN-US/library/aa569637.aspx

Index Hints:
-Default (best practice) = disabled. See also: Application Object Server (AOS) configuration commands [AX 2012]
LTrim:
-Default = enabled. Best practice = disabled. See also: Application Object Server (AOS) configuration commands [AX 2012]
Maximum buffer size:
-Defaults (best practice): 24kb (AX 2012 R2 & R3=48kb). See also: Tune data access settings [AX 2012]. Not to be confused with MaxBufferSize registry key below.
Statement cache:
-Defaults (best practice): AX 2012 RTM = 256, AX 2012 R2 & R3 = 450
Debug settings:
-Enable breakpoints to debug X++ code running on this server & Enable global breakpoints. Default (best practice): disabled (in production).
Literals:
-Use literals in complex joins from X++; Use literals in join queries from forms and reports. Defaults (best practice): disabled.
Minimum packet size to compress (in KB):
-Default (best practice) = 1kb.
Enable the hot-swapping of assemblies for each development session:
-Default (best practice) = disabled.
Generate ORDER BY clauses from WHERE clauses :
-Default (best practice) = disabled.
Maximum open cursors:
-Default (best practice)=90.See also: http://blogs.msdn.com/b/axsa/archive/2013/03/11/maximum-open-cursors-in-dynamics-ax.aspx
Additional AOS commands:
-Default (best practice) = none.

Processor affinity

-Default (best practice) = disabled. However if you must have more than one AOS instance per server, enable it to reduce context switching.
 
How to...

Divide the number of AOS processors equally among the instances, e.g. with 4 processors and 2 AOS services on one machine: processors 1 & 2 = AOS instance 1, processors 3 & 4 = AOS instance 2.

Set processor affinity [AX 2012]:
http://technet.microsoft.com/en-us/library/dd309629.aspx

Context_Info (AX 2012 only) [registry setting]:
-Default = disabled. Small performance overhead but recommended for troubleshooting. http://blogs.msdn.com/b/amitkulkarni/archive/2011/08/10/finding-user-sessions-from-spid-in-dynamics-ax-2012.aspx
MaxBufferSize [registry setting]:
Defaults: AX 2009 =  10MB, AX 2012 = 50MB.
 
How to...
http://blogs.msdn.com/b/emeadaxsupport/archive/2009/06/15/error-executing-code-insufficient-memory-to-run-script.aspx
Note: Although the blog covers AX 4.0 and AX 2009, a similar principle applies to AX 2012 as well. Just change the registry key names in the blog from 4.0 or 5.0, to 6.0. e.g.: Client key would be [HKEY_CURRENT_USER\Software\Microsoft\Dynamics\6.0\Configuration\(configuration name)]

AX Performance Troubleshooting Checklist Part 1A [Introduction and SQL Configuration]

$
0
0

Introduction

This check list is primarily aimed at troubleshooting general performance issues in Microsoft Dynamics AX 2009 and 2012. 'General' here typically means a set of unidentified issues across one or more modules, or indeed the entire application. However it is good practice to have  at least a quick check of set up and settings when working with any performance issue. It is important to always have a good foundation to diagnose issues from.

It is based on issues encountered on support and best practice documentation. As always, you should be sure that you fully understand the impact of any changes you make and implement them in your test environment first.

Part 1 covers SQL and AX configuration and is intended to give you the foundation. This in turn is split into 2 parts: 

  • SQL Server and Storage Settings (this page).
  • AX application and AOS configuration (page 2).

Part 2 (following on later) will cover hardware, indexing, queries,  blocking and code (at a high level). This naturally involves deeper analysis, which will be iterative and is probably where the vast majority of the time will be spent - but it requires a solid foundation (i.e. part 1).

It is suggested that you analyse/implement changes in three phases - Part 1, Part 2 (except code), code review, however each phase may overlap. You should also plan to spread out your deployments (of any remediation activities for this) as much as possible, for easier diagnosis and reversibility in case of any problems.

Within each section below, the links under 'Recommendation' relate to further details, while the links under 'How to...' relate to implementing the changes. You should ensure you have the information relevant to your software versions.

With each part, there will be a link to an analysis script which you can use to help gather the information from your system. These scripts require the Performance Analyser to be installed:

http://blogs.msdn.com/b/axinthefield/archive/2014/05/29/performance-analyzer-for-microsoft-dynamics-1-20-deployment-guide.aspx

References:

Part 1A: SQL Server and storage settings

Analysis script: http://blogs.msdn.com/b/axsupport/archive/2014/09/01/microsoft-dynamics-ax-general-performance-analysis-scripts.aspx

Infrastructure / assumptions:

-You are following the documented best practices for Windows Server and SQL Server.
-You are using a dedicated server that is appropriately sized according to the workload and meets the relevant system requirements (above).
-You are using a single instance of SQL Server that is dedicated to running the Microsoft Dynamics AX production databases.
-We recommend that you store your test and development databases on a separate server from the production databases.
-SQL Server settings: Affinity Masks and Priority boost are left as default (automatic and off respectively).

Virtualisation

Recommendation:
-While there are clear benefits from using virtualisation, it has been known to degrade performance under high load scenarios; if the virtualisation is not optimally configured then obviously the severity can increase. See "Virtual server support" in the system requirements.
 
See also: Hyper-V Benchmark for Microsoft Dynamics AX 2012
 
How to...
-Refer to your hardware/infrastructure vendor for advice.

 

OS

Recommendation:
-Verify that SQL Server is configured to run as a background service in Windows.
-Set the power plan to 'high performance' (all AX servers):
    http://blogs.msdn.com/b/axsupport/archive/2014/01/10/dynamics-ax-power-options.aspx
-[AX 2009 only] In Windows Server 2003, set the Specify memory usage option to Programs.
-[AX 2009 only] If you are using Windows Server 2003 with AMD processors, ensure that boot.ini contains the parameter /USEPMTIMER
 
How to...
Configure Application Performance on Windows Server 2008 R2:
http://technet.microsoft.com/en-us/magazine/ff458358.aspx

SQL Server Instance

Recommendation:
-Set max degree of parallelism to 1 (for normal Production operations)
-Max Server Memory: make sure that sufficient memory is available for the operation of Windows Server. Use the Memory: Available Mbytes performance counter for the Windows Server operating system to determine whether the available memory drops below 500 MB for extended periods
-AWE enabled on large memory 32bit systems [AX 2009]
-Check for large TokenAndPermUserStore (> a few hundred MB)
http://community.dynamics.com/ax/b/axinthefield/archive/2011/01/14/degraded-performance-on-dynamics-ax-and-the-sql-server-tokenandpermuserstore.aspx
 
How to...
Max Degree of Parallelism Option:
http://msdn.microsoft.com/en-us/library/ms181007.aspx
 
Windows Performance Monitor:
http://technet.microsoft.com/en-us/library/cc749249.aspx
 
Memory Architecture [AWE]:
http://msdn.microsoft.com/en-us/library/ms187499.aspx

SQL Server Service

Recommendation:
-Confirm that the account for the SQL Server service has been granted the Lock pages in memory privilege.
-Configure the account for the SQL Server service for instant file initialization.
-Enable only the required network protocols - AX only requires TCP/IP.
-Disable hyper-threading.
 
How to...

Enable the Lock Pages in Memory Option (Windows):
http://technet.microsoft.com/en-us/library/ms190730.aspx

Database Instant File Initialization:
http://technet.microsoft.com/en-us/library/ms175935.aspx

Enable or Disable a Server Network Protocol:
http://msdn.microsoft.com/en-us/library/ms191294.aspx

Disabling of Hyper-threading must be performed in the BIOS settings of the server. For instructions, see the hardware documentation for your server.

TempDB storage

Recommendation:
-Set a specific value (MB, not %) for autogrowth (safety mechanism, i.e. "emergency release valve" only)
-1 tempdb file per processor.
-Isolate tempdb on dedicated storage (highest speed possible)
-Determine the size of the tempdb data files and log files
 
How to...
 
Optimizing tempdb Performance:
http://msdn.microsoft.com/en-us/library/ms175527.aspx
 
ALTER DATABASE File and Filegroup Options (Transact-SQL):
http://technet.microsoft.com/en-us/library/bb522469(v=sql.120).aspx
 
Move System Databases:
http://msdn.microsoft.com/en-us/library/ms345408.aspx

AX Database Configuration:

Recommendation:
-Set COMPATIBILITY_LEVEL to 110 for SQL Server 2012, or to 100 for SQL Server 2008 or SQL Server 2008 R2
-Set READ_COMMITTED_SNAPSHOT to on
-Set AUTO_CREATE_STATISTICS and AUTO_UPDATE_STATISTICS to on. Set AUTO_UPDATE_STATISTICS_ASYNC to off.
-Make sure that the AUTO_SHRINK option is set to off
-All Microsoft Dynamics AX databases must use the same SQL collation.
 
How to...
 
ALTER DATABASE Compatibility Level (Transact-SQL):
http://msdn.microsoft.com/en-us/library/bb510680.aspx
 
ALTER DATABASE SET Options (Transact-SQL):
http://technet.microsoft.com/en-us/library/bb522682(v=sql.120).aspx
 
Turn AUTO_SHRINK off:
http://blogs.msdn.com/b/sqlserverstorageengine/archive/2007/03/28/turn-auto-shrink-off.aspx
 
Server Configuration - Collation:
http://msdn.microsoft.com/en-us/library/cc281995.aspx

Configuring physical storage

Recommendation:
-Disk sector alignment: partition offset value must be a multiple of the stripe size (i.e. partition offset / stripe size resolves to an integer). File allocation unit size: bytes per cluster should usually be 64KB.
-Create the tempdb database files, data files for the Microsoft Dynamics AX database, and Microsoft Dynamics AX log files on disk arrays of type RAID 1, RAID 0 + 1, or RAID 10 (RAID 10 recommended).
-Store the data files for the Microsoft Dynamics AX database on separate physical stores from transaction log files.
-Store the tempdb data files on a separate physical store from the data files and log files for the Microsoft Dynamics AX database.
-Store other database files on separate physical stores from the data files and log files for tempdb and the Microsoft Dynamics AX database.
-Virtual log files for each database log file. VLF_Count > 10k requires attention.
 
How to...
 
Seek guidance from your SAN vendor or if they do not provide specific recommendations, refer to:
Disk Partition Alignment Best Practices for SQL Server
http://msdn.microsoft.com/en-us/library/dd758814(SQL.100).aspx
Seek guidance from your SAN vendor regarding RAID configuration.
 
Move User Databases:
http://msdn.microsoft.com/en-us/library/ms345483.aspx
 
Move System Databases:
http://msdn.microsoft.com/en-us/library/ms345408.aspx
 
SQL Server Transaction Log Architecture and Management (VLF_Count):
http://technet.microsoft.com/en-us/library/jj835093(v=sql.110).aspx

Trace flags

Recommendation:
-Generally for SQL Server the recommendation is only to implement trace flags to address the specific issues they are designed to address, however for AX the following are known to have a beneficial impact on performance and should therefore be considered:4199; 1117; 1118; 1224; 2371;7646*
-Establish the reasons behind any other trace flags being enabled.
*7646 does not apply to SQL Server 2012 and above.
See:
http://blogs.msdn.com/b/axinthefield/archive/2014/05/08/dynamics-ax-and-sql-server-trace-flags-quick-and-dirty.aspx
How to...
 
Verify which trace flags are turned on:
DBCC TRACESTATUS (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms187809.aspx
 
If any of the mentioned trace flags are not turned on (see left), consider adding them as start-up parameters:
Configure Server Startup Options (SQL Server Configuration Manager)
http://msdn.microsoft.com/en-us/library/ms345416.aspx

Parameter sniffing fix (dataareaid & partition literals)

Recommendation:
-Ensure you have implemented this important fix for general performance in AX.
 
How to...
SQL Server Parameter Sniffing with Dynamics AX, just plain evil:
http://blogs.msdn.com/b/axinthefield/archive/2014/01/09/sql-server-parameter-sniffing-with-dynamics-ax-just-plain-evil.aspx

SQL Server build

Recommendation:
-Most recent supported Service Pack together with a recent cumulative update.
 
How to...
 
First check the system requirements (above link) for the latest supported service pack. To obtain the above service pack, search for "How to obtain the latest service pack for [your SQL Server version]", e.g. "How to obtain the latest service pack for SQL Server 2012":
http://support.microsoft.com/kb/2755533
 
followed by:
"The [SQL Server version] builds that were released after [SQL Server version] [above Service Pack] was released", e.g.: "The SQL Server 2012 builds that were released after SQL Server 2012 Service Pack 1 was released:"
http://support.microsoft.com/kb/2772858

Triggers

Recommendation:
-In part 1 the action is just to list non standard triggers - investigate these in more detail in part 2.
 
How to...
SQL script:
USE DYNAMICSPERF
SELECT * FROM TRIGGER_TABLE

SQL Server Agent jobs

Recommendation:
-Is there a database backup job (among other reasons, transaction logs need regular backups to keep the sizes small)
-Ensure that you have an appropriate database maintenance strategy.
-Are there jobs that could stress the server? In part 1 the suggested action is just to list them, then investigate these in more detail in part 2.
 
How to...
Plan backup and recovery [AX 2012]:
http://technet.microsoft.com/en-us/library/dd361990.aspx

Planning backup and disaster recovery[AX 2009]:
http://technet.microsoft.com/en-us/library/dd309580(v=ax.50).aspx
 
Database Maintenance Strategies for Dynamics AX:
http://blogs.msdn.com/b/axinthefield/archive/2012/08/01/database-maintenance-strategies-for-dynamics-ax.aspx

Data archiving/purging

Recommendation:
-Keeping the amount of data in your database to a minimum can help with performance.
-Other than those mentioned in the blog (see right), also consider the following key tables:
  • Logs and batch tables under Administration/Inquiries [AX 2009] or System Administration/Inquiries [AX 2012]. For SQL statement trace log (SysTraceTableSQL) there is also a SQL Server Agent purge job in the Performance Analyser tool.
  • InventSumLogTTS table: run MRP with full regeneration periodically (or turn off Master Planning configuration key)].
How to...

Database Maintenance Strategies for Dynamics AX:
http://blogs.msdn.com/b/axinthefield/archive/2012/08/01/database-maintenance-strategies-for-dynamics-ax.aspx

How to accurately predict database growth in Dynamics AX:
http://blogs.msdn.com/b/axinthefield/archive/2011/06/12/how-to-accurately-predict-database-growth-in-dynamics-ax.aspx

           

 

 

AX Performance Troubleshooting Checklist Part 2

$
0
0

This is Part 2 of a two part troubleshooting check list for general performance on Microsoft Dynamics AX. This part includes  hardware, indexing, queries,  blocking and code - at a high level. Please note this is just an outline of key areas for general guidance and not an exhaustive list.

As you have landed here, you will probably be interested in this blog too:

Top 10 issues discovered from Dynamics AX Health Check*
http://blogs.msdn.com/b/axinthefield/archive/2013/06/18/top-10-issues-discovered-from-premier-field-engineer-dynamics-ax-health-check.aspx

*Available through Premier Support Services.

Part 2 naturally involves deeper analysis, which will be iterative and  is probably where the vast majority of the time will be spent - but it requires a solid foundation.

It is therefore recommended that you review  Part 1 first, which is split over 2 pages:

  • Introduction and SQL Server/storage settings.
  • AX application and AOS configuration settings.

As with Part 1, each area (below) includes a link to a SQL script (or perfmon templates in the case of hardware analysis), which can assist you with data collection.

 

Part 2A: SQL Server and AOS Logs

Subsets of both of the following sets of logs can be found in the Performance Analyser.

AOS: Windows Application and System Event Logs

Recommendation:

-One important example to look for affecting general performance:
"RPC error: RPC exception 1726 occurred in session X. No ping from XX. Terminating the session. SPID XX for session id XX is still present in the database. Please delete the SPID from the database."

See the following blogs. The first covers identifying the root cause, the second relates to resolving the issue if it is happening at the time.

Steps to trace an AX session in the application event log back to a user
http://blogs.msdn.com/b/axsupport/archive/2010/10/18/steps-to-trace-an-ax-session-in-the-application-event-log-back-to-a-user.aspx

Dynamics AX and little Orphaned SPID Annie
   http://blogs.msdn.com/b/axinthefield/archive/2014/01/13/dynamics-ax-and-little-orphaned-spid-annie.aspx

How to...
Connect to the SQL Server instance hosting your Performance Analyser database and run the following script:
USE DYNAMICSPERF
SELECT * FROM [dbo].[AOS_EVENTLOG]

SQL Server Logs

Recommendation:

-One important example to look for affecting general performance:

"SQL Server has encountered  x occurrence(s) of I/O requests taking longer than 15 seconds to complete on file x."

See the following blog in relation to diagnosing this particular error:
http://blogs.msdn.com/b/karthick_pk/archive/2012/06/26/io_2d00_bottlenecks.aspx

To investigate disk latency in more depth, in addition to perfmon you can also use PERF_HOURLY_IOSTATS_VW and PERF_IOSTATS_VW in the Performance Analyser.

How to...
Connect to the SQL Server instance hosting your Performance Analyser database and run the following script:
USE DYNAMICSPERF
SELECT * FROM SQLERRORLOG

 

Part 2B: Hardware

Analysis script:There is no SQL script as with other areas, but perfmon templates can be found in the Performance Analyser (details below).

Collect SQL Server perfmon logs for 24h

Recommendation
-Collect perfmon logs using the relevant Performance Analyser 1.20 SQL Server template over a 24 hour period to capture a 'typical day'.
 
How to...
See http://blogs.msdn.com/b/axinthefield/archive/2014/05/29/performance-analyzer-for-microsoft-dynamics-1-20-deployment-guide.aspx , section: 'Configure and Schedule Performance Counter Logging on Database Server'.

Collect AOS perfmon logs for 24h

Recommendation
-Collect perfmon logs using the relevant Performance Analyser 1.20 AOS template over a 24 hour period to capture a 'typical day'.
 
How to...
See http://blogs.msdn.com/b/axinthefield/archive/2014/05/29/performance-analyzer-for-microsoft-dynamics-1-20-deployment-guide-dynamics-ax-installation.aspx , section: 'Configure and Schedule Performance Counter Logging on AOS Server(s)'.

PAL (Performance Analysis of Logs) tool

Recommendation:
-Analyse the above logs that you collected to identify potential hardware bottlenecks. PAL is a useful tool to get started with this.
 
How to...
See http://pal.codeplex.com/.

 

Part 2C: Index analysis

Analysis script: http://blogs.msdn.com/b/axsupport/archive/2014/09/01/microsoft-dynamics-ax-general-performance-analysis-scripts-page-2.aspx

Note:

  • Index changes are implemented in the AOT in the AX application. Index analysis (similar to the other areas in part 2) is a huge area in itself, but I plan to provide an indexing primer for AX in a future post.
  • 'Disable' below means to disable the index in the AOT, which will remove the index from the underlying database. When disabling indexes, take care with unique indexes in particular. However there may be an alternative index that can be used to enforce uniqueness.

Indexes to disable

Recommendation:
-This is a high risk area; as always, but particularly important here: be sure you understand the impact of what you are doing before going ahead. That said, it still needs to be done to avoid potential blocking issues and long durations on update, insert and delete operations.
-Disable exact duplicates on the same table (it can happen!)
-Disable left key subsets: indexes on the same table where some of the keys match from left to right, for example Index1 has index keys A, B, C and Index2 has index keys A, B, C, D. Disable Index2 (if for example Index2 is unique and Index1 is not, you can then make Index1 unique
-Disable unused indexes: ensure you have taken into account periodic (monthly,quarterly,year end) processes. Usually I would suggest collecting index usage data continuously in the Performance Analyser and reviewing this on a quarterly basis. Of course if you added indexes recently or during the review period and know the reason why they were added, but they don't get the usage you expected you can always disable them earlier.
-Indexes with a high number of included columns: either reduce the included columns or disable the index, depending on how each index is used.
-Heavily updated indexes: Compare writes vs. reads. Consider disabling indexes with high writes vs. reads, or reducing the number of index columns. Avoid using highly updated columns, which can include enums , amounts and quantities (note this is a general rule again though; for example it may be valid for a high impact query using 'SELECT SUM(AMOUNT1)...' to have an included column on AMOUNT1).
-Recversion indexes: RECVERSION should not be a part of AX Indexes due to the frequency of updates. Either remove the column or disable the index depending on how the index is used.
 
How to...

After analysis using the above script (if you are sure the index won't be required and in accordance with your usual development/deployment procedures), set the enabled property on each relevant index to No.

Table Index Properties [AX 2012]
http://msdn.microsoft.com/en-us/library/aa881522.aspx

Non-clustered indexes

Recommendation:
-Missing indexes: see Query Analysis (Part 2D) below.
-Index scans: Add missing indexes in the first instance (see Part 2D below). This may result in unused or low usage indexes (originally used for scans but superseded by new indexes), which you can then disable once you are confident they are no longer required. As troubleshooting becomes more in depth, query tuning (in the code) may also be required.
-'Hidden index scans': This is an AX specific term. In a query execution plan it would appear to be a seek, hence the 'hidden' part. However the 'seek' is across an entire company (dataareaid) in AX, so due to the relatively high number of records it has to search through, it could be considered to be effectively a scan. Therefore the same advice as for index scans (above) will apply.
-Indexes in SQL but not AX: identify indexes that are not defined in the AOT. They should be added to the AOT to be properly tracked as part of your code deployments and not lost during synchronisation.
 
How to...

After analysis using the above script (and in accordance with your usual development/deployment procedures), create indexes as per the following procedure.

How to: Create an Index [AX 2012]
http://msdn.microsoft.com/en-us/library/aa607289.aspx

Clustered indexes

Recommendation:
-This is a high risk area so again be cautious and ensure you understand the impact, but if you get it right, it can in some cases lead to huge performance gains.
-Tables without clustered indexes: Add an appropriate clustered index. See http://www.microsoft.com/technet/prodtechnol/sql/bestpractice/clusivsh.mspx
-Changes to clustered indexes: As per the comments in the above Performance Analyser script, "Find clustered indexes that could be changed to one of the non-clustered indexes that has more usage than the clustered index [bearing in mind the above points]. This should be the LAST activity done in a performance tuning session. NOTE - CHANGING CLUSTERED INDEXES WILL TAKE A LONG TIME TO DO AND REQUIRES DOWNTIME TO IMPLEMENT."
 
How to...
Below is a few general points to consider when choosing a clustered index:
  1. You can use the index usage statistics for the table (history can be kept in Performance Analyser) to determine potential candidates.
  2. They are part of the physical structure of the table and determine the physical order of data.
  3. They are therefore good for queries returning large result sets or using 'order by'.
  4. Non-clustered indexes on the same table point to rows in the clustered index, so consider the impact on the table as a whole.
After analysis using the above script (and in accordance with your usual development/deployment procedures), change the ClusterIndex table property in the AOT to the name of the new clustered index. See http://msdn.microsoft.com/en-us/library/aa871620.aspx

Review

Recommendation:
-Review all of the above in conjunction with the Performance Analyser and the analysis scripts provided. Index tuning is an iterative process so usually at least a few cycles of review/analysis/development/deployment can be expected.
 
How to...
Using the above analysis script.

 

Part 2D: Query analysis

Analysis scripts:
http://blogs.msdn.com/b/axsupport/archive/2014/09/01/microsoft-dynamics-ax-general-performance-analysis-scripts-page-3.aspx
http://blogs.msdn.com/b/axsupport/archive/2014/09/01/microsoft-dynamics-ax-general-performance-analysis-scripts-page-8.aspx

Long queries from AX

Recommendation:

Iteratively review the long queries captured in the SQL statement trace log (SysTraceTableSQL table).

In addition to the above scripts, you can use the following one to get an overview:

USE DYNAMICSPERF

select
   --cast(CALL_STACK as nvarchar(max)) as call_stack, --uncomment this line to get the call stacks
   cast(sql_text as nvarchar(max)) as sql_text,
   min(sql_duration) as min_duration,
   max(sql_duration) as max_duration,
   avg(sql_duration) as avg_duration,
   sum(sql_duration) as total_duration,
   count(*) as execution_count
from [dbo].[AX_SQLTRACE_VW]
where sql_duration>0 --filter out anything other than long queries
and datepart(hh,CREATED_DATETIME) between 8 and 18 --long queries captured from the AX client during your typical business hours - change or comment as required
--and call_stack like '%_%' --filter by a particular class/method
--and sql_text like '%_%' --look for a particular SQL statement, e.g. one found in a blocking chain.
group by
--cast(CALL_STACK as nvarchar(max)), --also uncomment this line if you uncomment line 2
cast(sql_text as nvarchar(max))
order by sum(sql_duration) desc

How to...
  • Queries with a high execution count may be resolved by table caching changes (see checklist part 1) or reducing loops in the application code (identify and trace the AX process, then review the database calls column in Trace Parser).
  • Queries with a high average or max duration may be resolved by index changes.
  • Queries with a large difference between minimum and maximum duration could be impacted by environmental factors such as blocking (see below) or parameter sniffing (see checklist part 1).
  • This will usually leave some queries which either require code analysis (use the call stack and userid to get information on the AX process) or be 'by design' due to the required business logic.

Expensive queries

Recommendation:
-Review:
  • Queries consuming most TOTAL time on SQL Server
  • Queries potentially causing large disk i/o;
  • High execution count could be loops in application code.
How to...
Review execution plans and whether index changes may help. Try to find the source (e.g. SQL Agent job, AX call stack, etc.) and tune the query.

Missing index queries

Recommendation:
-Identify queries that the optimizer suspects can be optimized by new or changed indexes. NOTE: DO NOT add these indexes verbatim without deep analysis.  Large INCLUDED lists are NOT recommended for AX.
How to...
Create the index in the AOT after analysing the query execution plan(s) related to the missing index recommendation (query MISSING_INDEXES_CURR_VW in Performance Analyser to retrieve the execution plans - page 3 of the analysis scripts).

How to: Create an Index [AX 2012]
http://msdn.microsoft.com/en-us/library/aa607289.aspx

Scanning queries

Recommendation:
-Identify queries causing index / hidden scans in conjunction with index tuning above.
How to...
Review execution plans and whether index changes may help. Try to find the source and tune the query.

OPTION (FAST) queries

Recommendation:
-Find queries option(fast) set that have sort operations (AX only). Either we don't have an index to match the order by clause or the query is potentially to complex for SQL to pick that index.
How to...
Review execution plans and whether index changes may help. Try to find the source and tune the query.

Review

Recommendation:
Query tuning is an iterative process so usually at least a few cycles of review/analysis/development/deployment can be expected. Review all of the above in conjunction with baseline analysis queries to see which queries are faster, slower, etc between changes (remember that the baseline queries are only an indication and depend on multiple other factors that may be interacting between runs).
How to...
http://blogs.msdn.com/b/axinthefield/archive/2014/05/29/baselines-with-performance-analyzer-for-microsoft-dynamics-dynamicsperf-are-here.aspx

 

Part 2E: Blocking

Analysis script: http://blogs.msdn.com/b/axsupport/archive/2014/09/01/microsoft-dynamics-ax-general-performance-analysis-scripts-page-4.aspx

Performance analyser setup

Recommendation:
-Ensure that the SQL profiler trace is running and AX long query trace is running (part of Performance Analyser installation).
How to...
See Performance Analyser setup blogs:

AX trace collection

Recommendation:
-Try to collect AX server traces at the times when blocking is occurring (if possible).
AX 2012:
http://blogs.msdn.com/b/axperf/archive/2011/11/18/collect-ax-2012-event-traces-with-windows-performance-monitor.aspx
AX 2009:
http://blogs.msdn.com/b/axinthefield/archive/2010/12/28/dynamics-ax-tracing-part-1.aspx http://blogs.msdn.com/b/axinthefield/archive/2011/03/25/dynamics-ax-tracing-part-2.aspx

Blocking analysis

Recommendation:
-The are multiple potential root causes of blocking (it can often be a symptom of another underlying problem), which can include:
How to:

You can identify the blocked and blocking processes in AX from the AX call stacks, by correlating SQL statements in long query traces and/or AX traces with SQL statements in the SQL profiler trace.

Understanding and resolving SQL Server blocking problems:
http://support.microsoft.com/kb/224453

TempDB

Recommendation:
-Performance Analyser can be used to identify whether there is an allocation bottleneck on tempdb.
How to...
http://blogs.msdn.com/b/axinthefield/archive/2011/06/12/tempdb-blocking-with-dynamics-ax.aspx

Real time monitoring

Recommendation:
-Often blocking is best resolved by monitoring at the time it is occurring.
How to...
Do one of the following (depending on your AX version):http://www.microsoft.com/en-gb/download/details.aspx?id=29063
    (works with the following SQL Server versions: SQL Server 2008, SQL Server 2008 R2, SQL Server 2012, SQL Server 2014)

Deadlocks

Recommendation:
-If deadlocks were occurring you can see the details of these separately (including deadlock graphs) in the SQL profiler trace.
How to...
You can query DEFAULT_TRC_VW in Performance Analyser for deadlock events, then follow the advice below.

Analyze Deadlocks with SQL Server Profiler:
http://msdn.microsoft.com/en-us/library/ms188246.aspx

Further information:

 

Part 2F: BI Performance

General tips

Recommendation:

-Consider hosting SQL Server Reporting Services / SQL Server Analysis Services on a separate SQL server for improved performance and scalability.

-Review the following articles:

 

Part 2G: Network

Network

Recommendation:

-Confirm there are no losses of connectivity and minimum network requirements are being met as per the system requirements.

AX 2009 system requirements: http://www.microsoft.com/en-us/download/details.aspx?id=26568

AX 2012 system requirements: http://www.microsoft.com/en-us/download/details.aspx?id=11094

How to...

Review with your LAN/WAN provider.

There are various ways of checking this but with the relevant approval, you can run a simple ping test to a text file, i.e. in the command prompt:
ping [IP/machine name] -t >[filepath\filename].

Key points to check between:

  • SQL Server and AOS
  • AOS and Client
  • AOS and application files [AX 2009 and lower versions only]

 

For further information regarding AX architecture, see:

System architecture [AX 2012]
http://technet.microsoft.com/en-us/library/dd362112.aspx

AX 2009 implementation guide
http://www.microsoft.com/en-us/download/details.aspx?id=3974

 

Part 2H: Code review

Subsets of both of the following sets of logs can be found in the Performance Analyser.

Long query traces

Recommendation:

-You can use the call stacks from the long query traces to guide you in relation to processes which are intermittently slow, etc (see query analysis above).

See above ('Query analysis').

AX traces

Recommendation:

-Collect AX traces of specific processes when they are running slowly, then analyse using Trace Parser and identify bottlenecks.

Dynamics AX Trace Parser (Part 3)
http://blogs.msdn.com/b/axinthefield/archive/2011/06/26/dynamics-ax-tracing-part-3.aspx

Hotfixes

Recommendation:

-Use the issue search in https://lcs.dynamics.com/ to identify any kernel (binary) and/or application hotfixes which may help. The most effective searches are usually on specific methods (i.e. dependent on the above trace analysis).

How to...

See Microsoft Dynamics AX Lifecycle Services videos:
https://www.youtube.com/playlist?list=PLt7Ttvo8Z9w8luk6FdMZuhTMwA8Um9bc0

or alternatively the user guide:
http://technet.microsoft.com/en-us/library/dn268616.aspx

Custom code tuning

Recommendation:

-Tune and / or redesign any processes where custom code is the bottleneck (based on above trace analysis).

How to...

Refer to your application partner or development team for guidance.

See also:

The book 'Inside Microsoft Dynamics AX' for your AX version:
https://www.microsoftpressstore.com/search/index.aspx?query=inside+dynamics+ax&x=0&y=0

Code analysis best practices and tools:
http://community.dynamics.com/ax/b/axresources/archive/2014/07/18/performance-resources-for-microsoft-dynamics-ax.aspx#Code

AX Content: September release of Lifecycle Services (LCS)

$
0
0

It’s always fun to watch each month as each Microsoft Dynamics Lifecycle Services update comes out. Some months we have a lot of new features, and some months just a few, but the site continues to evolve rapidly.

The September release is now available and contains several new features to help you manage your AX 2012 projects.

New features

Here’s a list of the new features that have been added:

  • The Cloud-hosted environments tool now has customizable settings for domains, virtual networks, and user accounts.
  • The Issue search tool now shows planned and open regulatory features, and includes searchable resources for:
    • Regulatory feature updates
    • Regulatory white papers, registrations, and reports
  • The Infrastructure estimatortool:
    • Has become an independent tool that can be accessed outside of the Usage profiler tool
    • Can provide sizing estimates for non-production environments, such as development, test, or training environments
  • The Upgrade analysistool provides new summary information in the report that it generates.
  • Lifecycle Services is now supported on Safari (v5.1.7) and Firefox (v32).

A little bit of background

Lifecycle Services is a cloud-based, collaborative workspace that customers and partners can use to manage Microsoft Dynamics AX projects from pre-sales to implementation and operations. Based on the phase of your project and the industry you are working in, the site provides checklists and tools that help you manage the project. It also provides a dashboard so that you have a single place to get up-to-date project information.

Lifecycle Services is available to customers and partners as part of their support plans. You can access it with your CustomerSource or PartnerSource credentials.

To get the latest Lifecycle Services news

Subscribe to the Lifecycle Services blog to get updates about new features, which are added on a monthly basis. You’ll also receive notifications about when the Lifecycle Services site is down for monthly maintenance.

Sending emails from Dynamics AX to external domains using Exchange Online

$
0
0

When using Exchange Online as your SMTP server in Dynamics AX 2012, you may have encountered this issue when sending emails, for example notifications, by batch:

Method 'send' in COM object of class 'CDO.Message' returned error code 0x8004020F (<unknown>) which means: <unknown>.

The error only occurs when sending emails outside of your organization’s domain, for example to an outlook.com email address.

In your test environment you can make a small change to the sysmailer class to get more details on the exception. Basically add a try/catch block as follows:

Compile CIL (incremental), restart your AOS and test again. This time you will get a more detailed error message:

The server rejected one or more recipient addresses. The server response was: 550 5.7.0 Relay Access Denied.

To resolve this issue you have to configure a connector in your Exchange Online.

You will find the details here: http://technet.microsoft.com/en-us/library/dn554323(v=exchg.150).aspx

Log in to https://portal.office.com with your Admin account, then go to Admin > Exchange > Mail flow > connectors.

In the Incoming connectors section click on the + sign and configure your connector in order to allow SMTP relay from your AOS. This is just an example, you should be more restrictive:

  • Connector type: On premises
  • Opportunistic TLS
  • Domain restrictions: None
  • Scope: *
  • Sender IP Addresses: external IP address of the AOS

I hope this helps.

Bertrand

Viewing all 1498 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>