Axapta 谁在执行这个特定的查询?

Axapta 谁在执行这个特定的查询?,axapta,microsoft-dynamics,dynamics-ax-2012,Axapta,Microsoft Dynamics,Dynamics Ax 2012,正在寻找有关以下查询来源的帮助。此查询每5分钟对DynamicAX数据库执行一次,平均执行时间为25秒。我知道它来自我们的SSRS服务器,该服务器也托管了我们的ManagementReporter dbs,我找不到执行它的作业,因此我怀疑它来自某种应用程序 我想看看性能能否提高。从统计数据来看,modelSecurityRole和SubRole是重量级击球手 假设它不是一个用户生成的查询,这个过程的执行时间是不是标准,或者是我们可以优化的东西吗?p> IO统计数据: ... Table 'Wor

正在寻找有关以下查询来源的帮助。此查询每5分钟对DynamicAX数据库执行一次,平均执行时间为25秒。我知道它来自我们的SSRS服务器,该服务器也托管了我们的ManagementReporter dbs,我找不到执行它的作业,因此我怀疑它来自某种应用程序

我想看看性能能否提高。从统计数据来看,modelSecurityRole和SubRole是重量级击球手

假设它不是一个用户生成的查询,这个过程的执行时间是不是标准,或者是我们可以优化的东西吗?p> IO统计数据:

...
Table 'Workfile'. Scan count 16, logical reads 20288, physical reads 2516, read-ahead reads 17772, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ModelSecurityRole'. Scan count 805305, logical reads 2316945, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ModelSecuritySubRole'. Scan count 56649, logical reads 1501880, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
...
查询:

select T.USERKEY, T.NAME, T.ALIAS, T.DOMAIN, T.SECURITYID, MAX(T.GENERALLEDGERROLETYPE) GENERALLEDGERROLETYPE, T.COMPANYKEY, T.ISENABLED
from (
    select UI.RECID USERKEY, UI.NAME, UI.NETWORKALIAS ALIAS, UI.NETWORKDOMAIN DOMAIN, SID SECURITYID, 
        CASE st.AOTNAME 
            WHEN 'SysSecSecurityMaintain' THEN 5
            WHEN 'LedgerBalanceSheetDimMaintain' THEN 4
            WHEN 'LedgerFinancialJournalReportBGenerate' THEN 3
            WHEN 'LedgerBalanceSheetDimPrintGenerate' THEN 3
            WHEN 'LedgerViewFinancialStatement' THEN 2
        END GENERALLEDGERROLETYPE, l.RECID COMPANYKEY, UI.ENABLE ISENABLED
        from [MicrosoftDynamicsAX]..USERINFO UI
        inner join [MicrosoftDynamicsAX]..SECURITYUSERROLE sur on UI.ID = sur.USER_ and UI.PARTITION = sur.PARTITION
        inner join [MicrosoftDynamicsAX_Model]..SECURITYROLE sr on sur.SECURITYROLE = sr.RECID
            and (GETUTCDATE() between sur.VALIDFROM and sur.VALIDTO OR 
                (sur.VALIDFROM = '1/1/1900' and sur.VALIDTO = '1/1/1900'))
        inner join [MicrosoftDynamicsAX]..SECURITYUSERROLECONDITION c on c.SECURITYUSERROLE = sur.RECID and c.PARTITION = sur.PARTITION
        inner join (SELECT T1.SECURITYTASK AS SECURITYTASK
                        ,T2.SECURITYROLE AS SECURITYROLE
                    FROM [MicrosoftDynamicsAX_Model]..SECURITYROLETASKGRANT T1
                    CROSS JOIN [MicrosoftDynamicsAX_Model]..SECURITYROLEEXPLODEDGRAPH T2
                    WHERE (T1.SECURITYROLE = T2.SECURITYSUBROLE)
                    GROUP BY T1.SECURITYTASK
                        ,T2.SECURITYROLE) v on v.SECURITYROLE = sr.RECID 
        inner join [MicrosoftDynamicsAX_Model]..SECURITYTASKEXPLODEDGRAPH g on g.SECURITYTASK = v.SECURITYTASK
        inner join [MicrosoftDynamicsAX_Model]..SECURITYTASK st on g.SECURITYSUBTASK = st.RECID
        inner join (Select l.RECID, l.PARTITION, CI.DATAAREA from [MicrosoftDynamicsAX]..LEDGER l 
            inner hash join [MicrosoftDynamicsAX]..DIRPARTYTABLE CI on CI.PARTITION = l.PARTITION and l.PRIMARYFORLEGALENTITY = CI.RECID) l on UI.PARTITION = l.PARTITION and l.DATAAREA = c.DATAAREA
    Where 
        UI.EXTERNALUSER = 0 AND
        UI.[SID] != '' AND
        UI.[ACCOUNTTYPE] = 0 AND
        sur.ASSIGNMENTSTATUS = 1 AND
        st.AOTNAME in (
        'SysSecSecurityMaintain',
        'LedgerBalanceSheetDimMaintain', 
        'LedgerFinancialJournalReportBGenerate', 
        'LedgerBalanceSheetDimPrintGenerate',
        'LedgerViewFinancialStatement')
    union all
    -- get users and their assigned tasks for all companies where the task hasn't been constrained to a company
    select UI.RECID USERKEY, UI.NAME, UI.NETWORKALIAS ALIAS, UI.NETWORKDOMAIN DOMAIN, SID SECURITYID, 
        CASE st.AOTNAME 
            WHEN 'SysSecSecurityMaintain' THEN 5
            WHEN 'LedgerBalanceSheetDimMaintain' THEN 4
            WHEN 'LedgerFinancialJournalReportBGenerate' THEN 3
            WHEN 'LedgerBalanceSheetDimPrintGenerate' THEN 3
            WHEN 'LedgerViewFinancialStatement' THEN 2
        END GENERALLEDGERROLETYPE, l.RECID COMPANYKEY, UI.ENABLE ISENABLED
        from [MicrosoftDynamicsAX]..USERINFO UI
        inner join [MicrosoftDynamicsAX]..SECURITYUSERROLE sur on UI.ID = sur.USER_ and UI.PARTITION = sur.PARTITION
        inner join [MicrosoftDynamicsAX_Model]..SECURITYROLE sr on sur.SECURITYROLE = sr.RECID
            and (GETUTCDATE() between sur.VALIDFROM and sur.VALIDTO OR 
                (sur.VALIDFROM = '1/1/1900' and sur.VALIDTO = '1/1/1900'))
        inner join (SELECT T1.SECURITYTASK AS SECURITYTASK
                        ,T2.SECURITYROLE AS SECURITYROLE
                    FROM [MicrosoftDynamicsAX_Model]..SECURITYROLETASKGRANT T1
                    CROSS JOIN [MicrosoftDynamicsAX_Model]..SECURITYROLEEXPLODEDGRAPH T2
                    WHERE (T1.SECURITYROLE = T2.SECURITYSUBROLE)
                    GROUP BY T1.SECURITYTASK
                        ,T2.SECURITYROLE) v on v.SECURITYROLE = sr.RECID  
        inner join [MicrosoftDynamicsAX_Model]..SECURITYTASKEXPLODEDGRAPH g on g.SECURITYTASK = v.SECURITYTASK
        inner join [MicrosoftDynamicsAX_Model]..SECURITYTASK st on g.SECURITYSUBTASK = st.RECID
        inner join (Select l.RECID, l.PARTITION from [MicrosoftDynamicsAX]..LEDGER l 
            inner hash join [MicrosoftDynamicsAX]..DIRPARTYTABLE CI on CI.PARTITION = l.PARTITION and l.PRIMARYFORLEGALENTITY = CI.RECID) l on UI.PARTITION = l.PARTITION
    Where 
        UI.EXTERNALUSER = 0 AND
        UI.[SID] != '' AND
        UI.[ACCOUNTTYPE] = 0 AND
        sur.ASSIGNMENTSTATUS = 1 AND
        st.AOTNAME in (
        'LedgerBalanceSheetDimMaintain', 
        'LedgerFinancialJournalReportBGenerate', 
        'LedgerBalanceSheetDimPrintGenerate',
        'LedgerViewFinancialStatement',
        'SysSecSecurityMaintain')
        and not exists (select 1 from SECURITYUSERROLECONDITION c where c.SECURITYUSERROLE = sur.RECID and c.PARTITION = sur.PARTITION)
    union all
    -- get all administrators for all companies where the admin's aren't limited to specific companies
    select UI.RECID, UI.NAME, UI.NETWORKALIAS, UI.NETWORKDOMAIN, SID, 5 RoleType, l.RECID, UI.ENABLE ISENABLED
        from [MicrosoftDynamicsAX]..USERINFO UI
        inner join [MicrosoftDynamicsAX]..SECURITYUSERROLE sur on UI.ID = sur.USER_ and UI.PARTITION = sur.PARTITION
        inner join [MicrosoftDynamicsAX_Model]..SECURITYROLE sr on sr.RECID = sur.SECURITYROLE
            and (GETUTCDATE() between sur.VALIDFROM and sur.VALIDTO OR 
                (sur.VALIDFROM = '1/1/1900' and sur.VALIDTO = '1/1/1900'))
        inner join (Select l.RECID, l.PARTITION from [MicrosoftDynamicsAX]..LEDGER l 
            inner hash join [MicrosoftDynamicsAX]..DIRPARTYTABLE CI on CI.PARTITION = l.PARTITION and l.PRIMARYFORLEGALENTITY = CI.RECID) l on UI.PARTITION = l.PARTITION
        where
            UI.EXTERNALUSER = 0 AND
            UI.[SID] != '' AND
            UI.[ACCOUNTTYPE] = 0 AND
            sur.ASSIGNMENTSTATUS = 1 AND
            AOTNAME in ('SysSecSecurityAdministrator') 
    )
    T
    Group by T.USERKEY, T.NAME, T.ALIAS, T.DOMAIN, T.SECURITYID,  T.COMPANYKEY, T.ISENABLED
    order by T.COMPANYKEY

我使用的是最新版本的SQL 2012

这些查询是从Management Reporter生成的,您不能更改它们。您可以在AOT中为
[MicrosoftDynamicsAX]
数据库中的表添加索引,但不能为
[MicrosoftDynamicsAX\u Model]
数据库中的表添加索引

这意味着您的调优选项非常有限,我看到这个查询在不止一次情况下需要几秒钟,但IO的数量对我来说似乎不太合适

不过,我想到了几件事:

确保您的统计信息是最新的,并且也对模型数据库的索引进行了碎片整理。您可以使用常规维护计划、SQL语句或

确保您的ManagementReporter是最新的CU(ManagementReporter有自己的CU,与AX不同),他们的修复并不总是记录得很好,但他们可能已经更改了此查询

您没有使用SQL 2014,但我将在此处添加此信息,以供将来的读者使用。我已经在SQL 2014中多次看到此查询行为不当。因此,对于使用SQL 2014的用户,请确保您的SQL Server是最新的CU,因为自RTM版本以来已发布了许多修复程序。如果您仍然无法使查询在SQL 2014上运行(这在我身上已经发生过几次),您可以通过创建计划指南添加
选项(QUERYTRACEON 9481)
将此查询还原为使用旧的基数估计器,如下所示:

EXEC sp_create_plan_guide @name = N'[Management Reporter guide]', @stmt = N'<the exact text of the query, whitespace and linebreaks included>', @hints = N' OPTION(QUERYTRACEON 9481)'
GO
EXEC sp_create_plan_guide@name=N'[Management Reporter guide],@stmt=N'',@hits=N'选项(QUERYTRACEON 9481)'
去

不过,2014版的症状与您描述的不同,它运行了几分钟,消耗了大量CPU。

我认为这是
Management Reporter
服务之一。查看mgmt reporter服务器,您将看到两个以
Management…
开始运行的服务。不知道你会如何修改这个。我认为它可以获取用户/角色和分类账数据。我已经将其缩小到三个查询中的中间查询,而有问题的语句似乎是最后一个join子句中的子查询=
Select l.RECID,l.PARTITION from[MicrosoftDynamicsAX]…分类账l内部哈希连接[MicrosoftDynamicsAX]…CI.PARTITION=l.PARTITION和l.PRIMARYFORLEGALENTITY=CI.RECID上的DIRPARTYTABLE CI
。如果我删除“hash”提示,那么整个查询将在几秒钟内完成。SQL Server 2012上也存在同样的问题。与@Greg一样,我发现删除hash-join提示可以解决问题。但是,这不是我们要更改的代码,而是在Microsoft的应用程序中。@MarkFreeman您可以向他们申请支持票证,但如果您知道如何修复,您可以在等待新的累积更新时自己修复。很难想象删除哈希连接提示会以任何方式破坏代码。此产品由其他用户“拥有”(而且非常保守)团体,因此这既是一个技术问题,也是一个政治问题。我敦促他们同意应用据称解决了这个问题的CU14,我主张我们修改时间表,每小时而不是每5分钟运行一次该声明,以至少减少他们应用CU之前的痛苦。