SQL Server 替换子查询以提高性能

wj8zmpe1  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(133)

我正在尝试提高SQL Server中以下查询的性能:

WITH s
AS (
    SELECT src.[ITEMID] AS [Item Code]
        ,po.[ORDERACCOUNT] AS [Order Account]
        ,vpsj.[INVOICEACCOUNT] AS [Invoice Account]
        ,vpsj.[PURCHID] AS [PO Number]
        ,src.[INVENTDIMID] AS [Inventory Dimension Id]
        ,po.[PURCHREQLINEREFID] AS [Reference Id]
        ,po.[PURCHPOOLID] AS [Purchase Pool Code]
        ,po.[ITEMBUYERGROUPID] AS [Inventory Buyer Group Code]
        ,cast(0 AS [bigint]) AS [Category Id]
        ,(
            SELECT TOP (1) lt.LEDGERDIMENSION
            FROM [dbo].[EALedgerTransactions] lt
            WHERE lt.[PARTITION] = src.[PARTITION]
                AND lt.[VOUCHERDATAAREAID] = src.[COMPANYCODE]
                AND lt.[VOUCHER] = src.[COSTLEDGERVOUCHER]
                AND lt.[POSTINGTYPE] IN (82,83)
            ) AS [Ledger Dimension Id]
        ,(
            SELECT TOP (1) lt.MAINACCOUNTID
            FROM [dbo].[EALedgerTransactions] lt
            WHERE lt.[PARTITION] = src.[PARTITION]
                AND lt.[VOUCHERDATAAREAID] = src.[COMPANYCODE]
                AND lt.[VOUCHER] = src.[COSTLEDGERVOUCHER]
                AND lt.[POSTINGTYPE] IN (82,83)
            ) AS [Main Account Id]
        ,src.[RECORDID] AS [Record Id]
        ,src.[COMPANYCODE] AS [Company Code]
        ,dateadd(day, datediff(day, 0, po.[CREATEDDATEANDTIME] - getutcdate() + getutcdate()), 0) AS [PO Date],
        po.[CURRENCYCODE] AS [Currency Code]
        ,src.[SOURCEDOCUMENTLINE] AS [Source Document Line Id]
        ,src.[ACCOUNTINGDATE] AS [Transaction Date]
        ,vpsj.[PACKINGSLIPID] AS [Product Receipt]
        ,cast(NULL AS [nvarchar](20)) AS [Invoice Number]
        ,src.[PURCHUNIT] AS [Purchase Unit]
        ,cast(NULL AS [nvarchar](20)) AS [Inventory Unit]
        ,po.[POAMOUNT] / nullif(po.[POQUANTITY], 0.0) AS [Purchase Price]
        ,src.[QTY] AS [Receipt Quantity]
        ,src.[INVENTQTY] AS [Receipt Inventory Quantity]
        ,src.[VALUEMST] AS [Receipt Amount Master]
        ,(
            SELECT sum(QTY) AS QTY
            FROM [dbo].[EAVendorPackingslipTransactions] pst
            WHERE pst.[PARTITION] = src.[PARTITION]
                AND pst.[COMPANYCODE] = src.[COMPANYCODE]
                AND pst.[COSTLEDGERVOUCHER] = src.[COSTLEDGERVOUCHER]
            ) AS [Voucher Quantity]
        ,(
            SELECT sum(ACCOUNTINGCURRENCYAMOUNT) AS ACCOUNTINGCURRENCYAMOUNT
            FROM [dbo].[EALedgerTransactions] lt
            WHERE lt.[PARTITION] = src.[PARTITION]
                AND lt.[VOUCHERDATAAREAID] = src.[COMPANYCODE]
                AND lt.[VOUCHER] = src.[COSTLEDGERVOUCHER]
                AND lt.[POSTINGTYPE] IN (82,83)
            ) AS [GRNI Amount Master]
        ,(
            SELECT sum(TRANSACTIONCURRENCYAMOUNT) AS TRANSACTIONCURRENCYAMOUNT
            FROM [dbo].[EALedgerTransactions] lt
            WHERE lt.[PARTITION] = src.[PARTITION]
                AND lt.[VOUCHERDATAAREAID] = src.[COMPANYCODE]
                AND lt.[VOUCHER] = src.[COSTLEDGERVOUCHER]
                AND lt.[POSTINGTYPE] IN (82,83)
            ) AS [GRNI Amount]
    FROM [dbo].[EAVendorPackingslipTransactions] src
    LEFT JOIN (
        SELECT [RECORDID]
            ,[INVOICEACCOUNT]
            ,[COMPANYCODE]
            ,[PURCHID]
            ,[PACKINGSLIPID]
            ,[ACCOUNTINGDATE]
            ,[LEDGERVOUCHER]
            ,[COSTLEDGERVOUCHER]
            ,rank() OVER (
                PARTITION BY [RECORDID] ORDER BY [VENDPACKINGSLIPVERSION_RECORDID] DESC
                ) AS [RANK]
        FROM [dbo].[EAVendorPackingslipJournals] vpsj
        ) vpsj ON vpsj.[RECORDID] = src.[VENDPACKINGSLIPJOUR]
        AND vpsj.[RANK] = 1
    LEFT JOIN [dbo].[EAPurchaseOrders] po ON po.[PARTITION] = src.[PARTITION]
        AND po.[COMPANYCODE] = src.[COMPANYCODE]
        AND po.[INVENTORYTRANSACTIONID] = src.[INVENTTRANSID]
    )

问题似乎出在subquires上,我一直在尝试用不同的joins来替换subquires,但到目前为止还没有成功(没有预期的值)。
关于如何替换子查询或其他内容有什么想法吗?
执行计划:

thtygnil

thtygnil1#

在没有数据的情况下很难进行测试,但您是否可以尝试将此查询作为您的起点:

select src.[ITEMID],src.[PARTITION],src.[COMPANYCODE],src.[COSTLEDGERVOUCHER]
        ,max(lt.LEDGERDIMENSION) as [Ledger Dimension Id]
        ,max(lt.MAINACCOUNTID) as [Main Account Id]
        ,sum(lt.QTY) AS [Voucher Quantity] 
        ,sum(lt.ACCOUNTINGCURRENCYAMOUNT) as [GRNI Amount Master]
        ,sum(lt.TRANSACTIONCURRENCYAMOUNT) as [GRNI Amount]
FROM [dbo].[EAVendorPackingslipTransactions] src
LEFT JOIn [EALedgerTransactions] lt
on lt.[PARTITION] = src.[PARTITION]
            AND lt.[VOUCHERDATAAREAID] = src.[COMPANYCODE]
            AND lt.[VOUCHER] = src.[COSTLEDGERVOUCHER]
            AND lt.[POSTINGTYPE] IN (82,83)

LEFT JOIN (
    SELECT [RECORDID]
        ,[INVOICEACCOUNT]
        ,[COMPANYCODE]
        ,[PURCHID]
        ,[PACKINGSLIPID]
        ,[ACCOUNTINGDATE]
        ,[LEDGERVOUCHER]
        ,[COSTLEDGERVOUCHER]
        ,rank() OVER (
            PARTITION BY [RECORDID] ORDER BY [VENDPACKINGSLIPVERSION_RECORDID] DESC
            ) AS [RANK]
    FROM [dbo].[EAVendorPackingslipJournals] vpsj
    ) vpsj ON vpsj.[RECORDID] = src.[VENDPACKINGSLIPJOUR]
    AND vpsj.[RANK] = 1
LEFT JOIN [dbo].[EAPurchaseOrders] po ON po.[PARTITION] = src.[PARTITION]
    AND po.[COMPANYCODE] = src.[COMPANYCODE]
    AND po.[INVENTORYTRANSACTIONID] = src.[INVENTTRANSID]
group by src.[ITEMID],src.[PARTITION],src.[COMPANYCODE],src.[COSTLEDGERVOUCHER]

它不使用子查询,而是一次性连接到EALedgerTransactions表,然后使用Group By创建数据组,使用MAX获得前1个结果,使用SUM获得组内的总计。

相关问题