簡體   English   中英

如何在AX查詢中提高左聯接的性能

[英]How to improve performance of left join in AX Query

我正在嘗試創建一個查詢,以在左聯接中獲取動態AX Salestable記錄及其歷史記錄記錄。 如果我對salesid進行過濾,我自然會在一秒鍾內得到結果,但是如果我省略了salesid,即使SalesID SN16129492是2017/03/08唯一的“有效”記錄,它也將永遠存在:

Declare @Bedrijf NVARCHAR(3) = 'dat';
Declare @leverdatum_van DATE = convert(datetime, '2017/03/08');
Declare @leverdatum_tot DATE = convert(datetime, '2017/03/08');
Declare @bedrag decimal = 1;

SELECT     SUM(SALESLINE.LINEAMOUNT) AS waarde, SALESTABLE.CUSTACCOUNT, SALESTABLE.SALESID as ordernummer, CUSTTABLE.NAME as klantnaam,
MAX(SalesTable.createdBy) as ingevoerd_door, log.dader, log.veldnummer, log.huidigestatus, log.vorigestatus

FROM         SALESLINE INNER JOIN
                      SALESTABLE ON SALESLINE.SALESID = SALESTABLE.SALESID AND SALESLINE.DATAAREAID = SALESTABLE.DATAAREAID 
                      INNER JOIN CUSTTABLE ON
SALESTABLE.DATAAREAID=CUSTTABLE.DATAAREAID AND SALESTABLE.CUSTACCOUNT=CUSTTABLE.ACCOUNTNUM
LEFT JOIN 
(select dbo.CONPEEK(CAST(dbo.CONPEEK(data, 2) AS varbinary(8000)), 2) AS DADER,
dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS varbinary(8000)), 1) AS VELDNUMMER,
dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS varbinary(8000)), 2) AS HUIDIGESTATUS,
dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS varbinary(8000)), 3) AS VORIGESTATUS,  LOGRECID 
from SYSDATABASELOG
where TABLE_=366 AND DATAAREAID=@bedrijf 
) log
ON SALESTABLE.DATAAREAID=@bedrijf AND SALESTABLE.RECID=log.LOGRECID
WHERE (SALESLINE.DATAAREAID = @bedrijf) AND SALESTABLE.SALESTYPE=4 --retourorder
AND     (SALESTABLE.SHIPPINGDATEREQUESTED between @leverdatum_van and @leverdatum_tot) 
--AND (Salestable.SALESID = 'SN16129492')
AND (SALESTABLE.SalesOrderStatus in (0,1,2,3,4,5)) 

GROUP BY SALESTABLE.CUSTACCOUNT, SALESTABLE.SALESID, CUSTTABLE.NAME, log.dader, log.veldnummer, log.huidigestatus, log.vorigestatus
HAVING     (SUM(ABS(SALESLINE.LINEAMOUNT))> @bedrag)

有沒有辦法提高性能/重新設計此查詢?

執行計划

即使您只有一個分區必須在所有表的條件中顯式包括dataareaid AND分區(可以將其添加為過濾器,也可以添加為聯接條件)。

默認情況下,AX2012作為前兩個字段將dataareaid和partition字段隱式添加到AOT中創建的所有索引中。

我們發現,眾所周知,SQL Server在處理這類索引方面很糟糕,除了如果您不明確提供它(分區)不能僅僅“跳過”第一級,它的確也很糟糕估計索引統計信息(SQL Server對索引中的第一個字段執行直方圖,並假定索引中的其余字段具有正態分布)。

這不是答案,但是我不能在注釋中寫這么長時間的代碼。 結果可能有所不同,但這只是為了幫助我們了解查詢的一部分是否會降低性能(GROUP BY)。 我將部分組字段移到了外面。 您可以嘗試一下,看看它是否“永遠地前進”(用您的話說)?

 SELECT A.*
        ,log.dader
        ,log.veldnummer
        ,log.huidigestatus
        ,log.vorigestatus
    FROM (
            SELECT SUM(SALESLINE.LINEAMOUNT) AS waarde
                ,SALESTABLE.CUSTACCOUNT
                ,SALESTABLE.SALESID AS ordernummer
                ,CUSTTABLE.NAME AS klantnaam
                ,MAX(SalesTable.createdBy) AS ingevoerd_door
                ,SALESTABLE.RECID    /* ADDED THIS */
            FROM SALESLINE
            INNER JOIN SALESTABLE ON SALESLINE.SALESID = SALESTABLE.SALESID AND SALESLINE.DATAAREAID = SALESTABLE.DATAAREAID
            INNER JOIN CUSTTABLE ON SALESTABLE.DATAAREAID = CUSTTABLE.DATAAREAID AND SALESTABLE.CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM
            WHERE SALESLINE.DATAAREAID = @bedrijf
                AND SALESTABLE.SALESTYPE = 4 --retourorder
                AND SALESTABLE.SHIPPINGDATEREQUESTED BETWEEN @leverdatum_van AND @leverdatum_tot
                --AND (Salestable.SALESID = 'SN16129492')
                AND SALESTABLE.SalesOrderStatus IN (0, 1, 2, 3, 4, 5)
            GROUP BY SALESTABLE.CUSTACCOUNT
                ,SALESTABLE.SALESID
                ,CUSTTABLE.NAME
                ,SALESTABLE.RECID    /* ADDED THIS */
            HAVING SUM(ABS(SALESLINE.LINEAMOUNT)) > @bedrag
            ) A
    LEFT JOIN (SELECT dbo.CONPEEK(CAST(dbo.CONPEEK(data, 2) AS VARBINARY(8000)), 2) AS DADER
                ,dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS VARBINARY(8000)), 1) AS VELDNUMMER
                ,dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS VARBINARY(8000)), 2) AS HUIDIGESTATUS
                ,dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS VARBINARY(8000)), 3) AS VORIGESTATUS
                ,LOGRECID
                FROM SYSDATABASELOG
                WHERE TABLE_ = 366
                AND DATAAREAID = @bedrijf) log ON SALESTABLE.RECID = log.LOGRECID

通過為bot左右表添加針對createddatetime的過濾器,我將處理時間從“永久”減少到了不到30秒,持續了一個月。

優化查詢:

Declare @Bedrijf NVARCHAR(3) = 'dat';
Declare @leverdatum_van DATETIME = convert(datetime, '2017/03/01');
Declare @leverdatum_tot DATETIME = convert(datetime, '2017/04/01');
Declare @bedrag decimal = 1;

SELECT     SUM(SALESLINE.LINEAMOUNT) AS waarde, SALESTABLE.CUSTACCOUNT, SALESTABLE.SALESID as ordernummer, CUSTTABLE.NAME as klantnaam,
MAX(SalesTable.createdBy) as ingevoerd_door, log.dader, log.veldnummer, log.huidigestatus, log.vorigestatus
FROM     SALESLINE 
INNER JOIN SALESTABLE 
ON SALESLINE.SALESID = SALESTABLE.SALESID AND SALESLINE.DATAAREAID = SALESTABLE.DATAAREAID 
INNER JOIN CUSTTABLE 
ON SALESTABLE.DATAAREAID=CUSTTABLE.DATAAREAID AND SALESTABLE.CUSTACCOUNT=CUSTTABLE.ACCOUNTNUM
LEFT JOIN  (
                           select dbo.CONPEEK(CAST(dbo.CONPEEK(data, 2) AS varbinary(8000)), 2) AS DADER,
                                        dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS varbinary(8000)), 1) AS VELDNUMMER,
                                        dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS varbinary(8000)), 2) AS HUIDIGESTATUS,
                                        dbo.CONPEEK(CAST(dbo.CONPEEK(data, 5) AS varbinary(8000)), 3) AS VORIGESTATUS,  LOGRECID 
                           from SYSDATABASELOG
                           where TABLE_=366 AND DATAAREAID=@bedrijf 
                           and createddatetime between @leverdatum_van and @leverdatum_tot
                    ) log
ON SALESTABLE.DATAAREAID=@bedrijf AND SALESTABLE.RECID=log.LOGRECID
WHERE (SALESLINE.DATAAREAID = @bedrijf) AND SALESTABLE.SALESTYPE=4 --retourorder
AND     (SALESTABLE.createddatetime between @leverdatum_van and @leverdatum_tot) 
--AND (Salestable.SALESID = 'SN16129492')
AND (SALESTABLE.SalesOrderStatus in (0,1,2,3,4,5)) 
GROUP BY SALESTABLE.CUSTACCOUNT, SALESTABLE.SALESID, CUSTTABLE.NAME, log.dader, log.veldnummer, log.huidigestatus, log.vorigestatus
HAVING     (SUM(ABS(SALESLINE.LINEAMOUNT))> @bedrag)

在新的執行計划中尋求更多的聚集索引: 優化后的執行計划

謝謝你幫我;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM