此存储过程是我正在处理的报告的一部分。因此,准确地说,它运行非常慢,运行非常慢,需要48分钟。通过在下面看到的联接中删除or运算符,我可以在6秒钟内运行它。现在,它不返回重复项,而是返回两个表中的数据,这为我的结果集中添加了更多行。问题是 两个联接,分别是FinancialTransactions ft,FinancialTransactions ftRec
我尝试使用CTE。我将联接拆分并合并所有它们。我无法向查询添加索引或创建任何视图。我还加入了另一个表以及另一个视图,该视图返回了更多需要的行。
Before Fix
SELECT DISTINCT
1 as SourceId,
l.LotID as 'LotId',
r.Id as 'RecoveryId',
acc.AccountName as 'Account',
r.BillingCode as BillingCode,
r.ProjectCode as ProjectCode,
a.AssetID as 'SSE Number',
' ' as 'ParentSSENumber',
COALESCE(ft.InvoiceNumber,ftrec.InvoiceNumber) as InvoiceNumber,
COALESCE(ft.InvoicedOn,ftrec.InvoicedOn) as InvoiceDate,
a.Class AS Category,
a.Manufacturer,
a.Product AS Model,
a.ProductNumber AS ModelNum,
a.SerialNumber AS SerialNum,
a.CustomerAssetNumber AS CustAssetTag,
a.Weight,
@WeightMeasure AS WeightMeasurement,
CASE a.ClassID --a.LockedStatus
WHEN 919
THEN CASE hdd.Disposition
WHEN 'Inventory'
THEN
CASE
WHEN -ft.Rate > 0
THEN 'Resale'
ELSE 'Active' END
ELSE hdd.Disposition END
ELSE
CASE --ISNULL(A.LockedStatus, - 1)
WHEN A.LockedStatus = -1 THEN 'InProduction'
WHEN A.LockedStatus = 1 THEN 'Active'
WHEN A.LockedStatus = 2 THEN 'On Hold'
WHEN A.LockedStatus = 3 AND iph_gen.PurchaseType = 7 THEN 'Redeployment'
WHEN A.LockedStatus = 3 AND iph_gen.PurchaseType = 12 THEN 'Donation'
WHEN A.LockedStatus = 3 AND iph_gen.PurchaseType = 11 THEN 'Legal Hold Release'
WHEN A.LockedStatus = 3 AND iph_gen.PurchaseType NOT IN (7,11,12) THEN 'Sold'
WHEN A.LockedStatus = 4 THEN 'Upgrade'
WHEN A.LockedStatus = 5 THEN 'Recycled'
WHEN A.LockedStatus = 6 THEN 'Sold Off-site'
ELSE ''
END
END
AS Disposition,
CASE WHEN a.LockedStatus = 5
THEN ftrec.CreatedOn
ELSE iph_gen.shipDate END AS DispositionDate,
'' AS Comments, --REPLACE(r.AdditionalNotes , CHAR(10), '') as Comments,
isnull(GTu.Name, 'N/A') AS FinalGrade,
' ', ' ',
ISNULL(CASE ftRec.RateTypeID WHEN 1 THEN a.Weight ELSE 1 END * ftRec.Rate,0) AS RecyclingFees,
-- ISNULL(ft.RemarketingPercentage,0),
isnull(ft.Rate,0) AS RemarketingCredit,
--isnull(gt.Name, 'N/A') AS RegisteredGrade,
--' ',
0.00 as LeaseReturnFee,
CASE WHEN iph_gen.PurchaseType = 7 THEN ISNULL(ipds_gen.Price,0)
ELSE 0.00
END AS RedploymentFee,
CASE WHEN ccsg.GroupName LIKE '%Donation%' THEN
CASE WHEN iph_gen.PurchaseType = 12 THEN ISNULL(ipds_gen.Price,0)
ELSE 0.00
END ELSE 0.00
END AS DonationFee
FROM vAssetSimpleView a
INNER JOIN itTransactionProcess AS tp ON tp.TransactionID = a.OrigTransactionID
INNER JOIN itLots AS l ON l.LotID = tp.LotNumber
LEFT JOIN [10.10.1.188,13151].Adviser.dbo.Recovery r on l.LotID = r.MRMLotId
--LEFT JOIN [54.84.218.110,13151].Adviser.dbo.Account acc on r.AccountId = acc.Id
LEFT OUTER JOIN AccountLocationOrderNo AS alon ON alon.LotID = l.LotID
LEFT JOIN AccountLocation AS al ON al.LocationID = l.LocationID
LEFT JOIN Account acc ON al.accountId = acc.AccountID
LEFT JOIN itDocks AS d ON d.DockID = l.DockScheduledOn
LEFT OUTER JOIN Contact AS c ON al.Contact_Onsite = c.ContactID
LEFT OUTER JOIN itGradeTypes AS g ON g.RecID = a.Grade
--JOINS FOR ORDERS
LEFT JOIN itPurchaseDetails ipd_gen on ipd_gen.assetid = a.assetid
LEFT JOIN itPurchaseDetailService ipds_gen on ipd_gen.RecID = ipds_gen.PurchaseDetailRecId
LEFT JOIN ContractCustomServiceGroups ccsg on ccsg.recid = ipds_gen.ServiceGroupId
--AND ipds_donation.ServiceGroupId IN (SELECT RecID FROM [ContractCustomServiceGroups] WHERE GroupName Like '%Donation%')
LEFT JOIN itPurchaseHeader iph_gen on ipd_gen.PurchaseHeaderRecID = iph_gen.RecID
--AND iph_donation.PurchaseType = 12
--END JOINS FOR ORDERS
LEFT OUTER JOIN dbo.Reporting_Inventory_Harddrives hdd ON hdd.AssetID = a.AssetID
--LEFT OUTER JOIN vAssetServicesByType vast ON a.AssetID = vast.AssetRecId
--OUTER APPLY
--(
-- SELECT ph.RecID AS OrderID, v.VendorName, ph.OrderDate,ph.shipdate, cup.FirstName + ' ' + cup.LastName AS SalesRep, pd.LineTotal AS ResalePrice
-- FROM dbo.itPurchaseDetails pd
-- INNER JOIN dbo.itPurchaseHeader ph ON ph.RecID = pd.PurchaseHeaderRecID
-- INNER JOIN dbo.itVendorLocation vl ON vl.LocationID = ph.VendorLocationID
-- INNER JOIN dbo.itVendor v ON v.VendorID = vl.VendorID
-- INNER JOIN dbo.aspnet_custom_UserProfiles cup ON cup.UserID = ph.CreatedBy
-- WHERE ph.Status > 1
-- AND pd.AssetID = a.AssetID
--) AS do
LEFT OUTER JOIN FinancialTransactions ft ON ((ft.FinancialTypeID = 9 AND ft.AssetID = a.AssetID) OR (ft.FinancialTypeID = 8 AND ft.FKeyID = a.OrigTransactionID AND ft.AssetID = 0))
LEFT OUTER JOIN FinancialTransactions ftRec ON ((ftRec.AssetID = a.AssetID) OR (ftRec.FKeyID = a.OrigTransactionID and ftRec.AssetID = 0)) AND ftRec.FinancialTypeID = 1
--OUTER APPLY
--(
-- SELECT ISNULL(SUM(csa.ServicePriceTotal),0) AS total
-- FROM ContractServicesApplied csa
-- WHERE csa.AssetID = a.AssetID
-- AND csa.Completed = 1
--) AS csa
--CROSS APPLY(SELECT ISNULL(SUM(T.PartValue),0) AS UpgradeValue
--FROM dbo.itAssetComponentTransactions AS T
--INNER JOIN dbo.itAssetComponents AS AC
--ON AC.RecID = T.AssetComponentID WHERE
--(T.AssetID = A.AssetId)
--AND (T.TransactionTypeID = 1) AND (AC.DateRemoved IS NULL)) as uv
--LEFT JOIN [dbo].[Reporting_Inventory_Harddrives] rih ON a.AssetId = rih.AssetId
--Tony Added For Recycling Fee Column
LEFT JOIN (SELECT tp.AssetId, -1*ft.Total AS RecyclingTotal
FROM itTransactionProcess tp
INNER JOIN itProcessSteps ps ON tp.NextProcessStepID = ps.ProcessStepID
LEFT OUTER JOIN FinancialTransactions ft ON ft.FKeyID = tp.TransactionID
INNER JOIN itLots il on tp.LotNumber = il.LotID
INNER JOIN AccountLocation al on al.LocationID = il.LocationID
INNER JOIN Account acc on al.AccountID = acc.accountId
WHERE acc.AccountID = @AccountId
AND ps.IsRecyclingProcess = 1
AND ps.IsEndProcess = 1 ) As Recycling ON a.AssetID = Recycling.AssetID
--End Recycling Join
--Tony Added to include Parts section in Asset Detail body of reports
LEFT JOIN itProcessSteps ps ON tp.NextProcessStepID = ps.ProcessStepID
--End Parts Join
--Tony Added for Grade/Condition data
LEFT OUTER JOIN dbo.itGradeTypes GT ON GT.RecID = a.Grade
INNER JOIN itAsset ia ON a.AssetID = ia.AssetRecId
LEFT OUTER JOIN dbo.itGradeTypes GTu ON GTu.RecID = ia.Upgrade_Grade --Join to asset because vAssetSimpleView does not have upgrade_grade
--End Grade Join
OUTER APPLY
(
SELECT TOP 1 CASE WHEN ps.IsRecyclingProcess = 1 THEN 'Recycled' WHEN ps.ProcessStepID = 25 THEN 'Resale' ELSE ps.Name END AS Disposition
FROM itTransactionProcess tp
INNER JOIN itProcessSteps ps on ps.ProcessStepID = tp.CurrentProcessStepID
WHERE tp.AssetID = a.AssetID
AND ps.IsEndProcess = 1
--AND a.AssetTypeID = 1
) AS assetDisp
WHERE acc.accountid = @AccountId
AND ((iph_gen.shipDate >= @StartDate AND iph_gen.ShipDate <= @EndDate) OR (a.LockedStatus = 5 AND ftrec.CreatedOn >= @StartDate AND ftrec.CreatedOn <= @EndDate))
AND ((a.AssetTypeID =1) OR (a.AssetTypeID = 2 and a.ClassID = 919) OR (a.AssetTypeID = 3 and a.ClassID = 919))
--make sure hard drives are part of the asset report
LEFT OUTER JOIN FinancialTransactions ftRec ON ((ftRec.AssetID = a.AssetID) OR (ftRec.FKeyID = a.OrigTransactionID and ftRec.AssetID = 0)) AND ftRec.FinancialTypeID = 1
--OUTER APPLY
After FIX
SELECT DISTINCT
1 as SourceId,
l.LotID as 'LotId',
r.Id as 'RecoveryId',
acc.AccountName as 'Account',
r.BillingCode as BillingCode,
r.ProjectCode as ProjectCode,
a.AssetID as 'SSE Number',
' ' as 'ParentSSENumber',
COALESCE(ft.InvoiceNumber,Ftrec.InvoiceNumber) as InvoiceNumber,
COALESCE(ft.InvoicedOn,Ftrec.Invoicedon) as InvoiceDate,
a.Class AS Category,
a.Manufacturer,
a.Product AS Model,
a.ProductNumber AS ModelNum,
a.SerialNumber AS SerialNum,
a.CustomerAssetNumber AS CustAssetTag,
a.Weight,
@WeightMeasure AS WeightMeasurement,
CASE a.ClassID --a.LockedStatus
WHEN 919
THEN CASE hdd.Disposition
WHEN 'Inventory'
THEN
CASE
WHEN -ft.Rate > 0
THEN 'Resale'
ELSE 'Active' END
ELSE hdd.Disposition END
ELSE
CASE --ISNULL(A.LockedStatus, - 1)
WHEN A.LockedStatus = -1 THEN 'InProduction'
WHEN A.LockedStatus = 1 THEN 'Active'
WHEN A.LockedStatus = 2 THEN 'On Hold'
WHEN A.LockedStatus = 3 AND iph_gen.PurchaseType = 7 THEN 'Redeployment'
WHEN A.LockedStatus = 3 AND iph_gen.PurchaseType = 12 THEN 'Donation'
WHEN A.LockedStatus = 3 AND iph_gen.PurchaseType = 11 THEN 'Legal Hold Release'
WHEN A.LockedStatus = 3 AND iph_gen.PurchaseType NOT IN (7,11,12) THEN 'Sold'
WHEN A.LockedStatus = 4 THEN 'Upgrade'
WHEN A.LockedStatus = 5 THEN 'Recycled'
WHEN A.LockedStatus = 6 THEN 'Sold Off-site'
ELSE ''
END
END
AS Disposition,
CASE WHEN a.LockedStatus = 5
THEN ftRec.CreatedOn
ELSE iph_gen.shipDate END AS DispositionDate,
'' AS Comments, --REPLACE(r.AdditionalNotes , CHAR(10), '') as Comments,
isnull(GTu.Name, 'N/A') AS FinalGrade,
' ', ' ',
ISNULL(CASE ftRec.RateTypeID WHEN 1 THEN a.Weight ELSE 1 END * ftRec.Rate,0) AS RecyclingFees,
-- ISNULL(ft.RemarketingPercentage,0),
isnull(ft.Rate,0) AS RemarketingCredit,
--isnull(gt.Name, 'N/A') AS RegisteredGrade,
--' ',
0.00 as LeaseReturnFee,
CASE WHEN iph_gen.PurchaseType = 7 THEN ISNULL(ipds_gen.Price,0)
ELSE 0.00
END AS RedploymentFee,
CASE WHEN ccsg.GroupName LIKE '%Donation%' THEN
CASE WHEN iph_gen.PurchaseType = 12 THEN ISNULL(ipds_gen.Price,0)
ELSE 0.00
END ELSE 0.00
END AS DonationFee
--Rank () over
-- (
-- PARTITION by [InviovceDate]
-- Order by [SSE Number] DESC
-- ) as rank
FROM vAssetSimpleView a
INNER JOIN itTransactionProcess AS tp ON tp.TransactionID = a.OrigTransactionID
INNER JOIN itLots AS l ON l.LotID = tp.LotNumber
LEFT JOIN [10.10.1.188,13151].Adviser.dbo.Recovery r on l.LotID = r.MRMLotId
--LEFT JOIN [54.84.218.110,13151].Adviser.dbo.Account acc on r.AccountId = acc.Id
LEFT OUTER JOIN AccountLocationOrderNo AS alon ON alon.LotID = l.LotID
LEFT JOIN AccountLocation AS al ON al.LocationID = l.LocationID
LEFT JOIN Account acc ON al.accountId = acc.AccountID
LEFT JOIN itDocks AS d ON d.DockID = l.DockScheduledOn
LEFT OUTER JOIN Contact AS c ON al.Contact_Onsite = c.ContactID
LEFT OUTER JOIN itGradeTypes AS g ON g.RecID = a.Grade
--JOINS FOR ORDERS
LEFT JOIN itPurchaseDetails ipd_gen on ipd_gen.assetid = a.assetid
LEFT JOIN itPurchaseDetailService ipds_gen on ipd_gen.RecID = ipds_gen.PurchaseDetailRecId
LEFT JOIN ContractCustomServiceGroups ccsg on ccsg.recid = ipds_gen.ServiceGroupId
--AND ipds_donation.ServiceGroupId IN (SELECT RecID FROM [ContractCustomServiceGroups] WHERE GroupName Like '%Donation%')
LEFT JOIN itPurchaseHeader iph_gen on ipd_gen.PurchaseHeaderRecID = iph_gen.RecID
--AND iph_donation.PurchaseType = 12
--END JOINS FOR ORDERS
LEFT OUTER JOIN dbo.Reporting_Inventory_Harddrives hdd ON hdd.AssetID = a.AssetID
--LEFT OUTER JOIN vAssetServicesByType vast ON a.AssetID = vast.AssetRecId
--OUTER APPLY
--(
-- SELECT ph.RecID AS OrderID, v.VendorName, ph.OrderDate,ph.shipdate, cup.FirstName + ' ' + cup.LastName AS SalesRep, pd.LineTotal AS ResalePrice
-- FROM dbo.itPurchaseDetails pd
-- INNER JOIN dbo.itPurchaseHeader ph ON ph.RecID = pd.PurchaseHeaderRecID
-- INNER JOIN dbo.itVendorLocation vl ON vl.LocationID = ph.VendorLocationID
-- INNER JOIN dbo.itVendor v ON v.VendorID = vl.VendorID
-- INNER JOIN dbo.aspnet_custom_UserProfiles cup ON cup.UserID = ph.CreatedBy
-- WHERE ph.Status > 1
-- AND pd.AssetID = a.AssetID
--) AS do
LEFT OUTER JOIN FinancialTransactions ft ON ft.FinancialTypeID = 9 AND ft.AssetID = a.AssetID
LEFT OUTER JOIN FinancialTransactions ft1 ON ft.FinancialTypeID = 8 AND ft.FKeyID = a.OrigTransactionID AND ft.AssetID = 0
LEFT OUTER JOIN FinancialTransactions ftRec ON ftRec.AssetID = a.AssetID
LEFT OUTER JOIN FinancialTransactions ftRec1 ON ftRec.FKeyID = a.OrigTransactionID and ftRec.AssetID = 0 AND ftRec.FinancialTypeID = 1
--LEFT OUTER JOIN FinancialTransactions ft ON ((ft.FinancialTypeID = 9 AND ft.AssetID = a.AssetID and (ft.FinancialTypeID = 8 AND ft.FKeyID = a.OrigTransactionID AND ft.AssetID = 0))
--LEFT OUTER JOIN FinancialTransactions ftRec ON ftRec.AssetID = a.AssetID and ftRec.FKeyID = a.OrigTransactionID and ftRec.AssetID = 0 AND ftRec.FinancialTypeID = 1
--OUTER APPLY
--(
-- SELECT ISNULL(SUM(csa.ServicePriceTotal),0) AS total
-- FROM ContractServicesApplied csa
-- WHERE csa.AssetID = a.AssetID
-- AND csa.Completed = 1
--) AS csa
--CROSS APPLY(SELECT ISNULL(SUM(T.PartValue),0) AS UpgradeValue
--FROM dbo.itAssetComponentTransactions AS T
--INNER JOIN dbo.itAssetComponents AS AC
--ON AC.RecID = T.AssetComponentID WHERE
--(T.AssetID = A.AssetId)
--AND (T.TransactionTypeID = 1) AND (AC.DateRemoved IS NULL)) as uv
--LEFT JOIN [dbo].[Reporting_Inventory_Harddrives] rih ON a.AssetId = rih.AssetId
--Tony Added For Recycling Fee Column
LEFT JOIN (SELECT tp.AssetId, -1*ft.Total AS RecyclingTotal
FROM itTransactionProcess tp
INNER JOIN itProcessSteps ps ON tp.NextProcessStepID = ps.ProcessStepID
LEFT OUTER JOIN FinancialTransactions ft ON ft.FKeyID = tp.TransactionID
INNER JOIN itLots il on tp.LotNumber = il.LotID
INNER JOIN AccountLocation al on al.LocationID = il.LocationID
INNER JOIN Account acc on al.AccountID = acc.accountId
WHERE acc.AccountID = @AccountId
AND ps.IsRecyclingProcess = 1
AND ps.IsEndProcess = 1 ) As Recycling ON a.AssetID = Recycling.AssetID
--End Recycling Join
--Tony Added to include Parts section in Asset Detail body of reports
LEFT JOIN itProcessSteps ps ON tp.NextProcessStepID = ps.ProcessStepID
--End Parts Join
--Tony Added for Grade/Condition data
LEFT OUTER JOIN dbo.itGradeTypes GT ON GT.RecID = a.Grade
INNER JOIN itAsset ia ON a.AssetID = ia.AssetRecId
LEFT OUTER JOIN dbo.itGradeTypes GTu ON GTu.RecID = ia.Upgrade_Grade --Join to asset because vAssetSimpleView does not have upgrade_grade
--End Grade Join
OUTER APPLY
(
SELECT TOP 1 CASE WHEN ps.IsRecyclingProcess = 1 THEN 'Recycled' WHEN ps.ProcessStepID = 25 THEN 'Resale' ELSE ps.Name END AS Disposition
FROM itTransactionProcess tp
INNER JOIN itProcessSteps ps on ps.ProcessStepID = tp.CurrentProcessStepID
WHERE tp.AssetID = a.AssetID
AND ps.IsEndProcess = 1
--AND a.AssetTypeID = 1
) AS assetDisp
WHERE acc.accountid = @AccountId
AND ((iph_gen.shipDate >= @StartDate AND iph_gen.ShipDate <= @EndDate) OR (a.LockedStatus = 5 AND ftRec.CreatedOn >= @StartDate AND ftRec.CreatedOn <= @EndDate))
AND ((a.AssetTypeID =1) OR (a.AssetTypeID = 2 and a.ClassID = 919) OR (a.AssetTypeID = 3 and a.ClassID = 919))
我知道proc的这一特定部分会降低性能。我希望能够以既能保持高速又能删除多余数据的方式编写这些联接。我试图添加执行计划,但是如果您可以对如何执行该操作有一些见解,那么我将无法执行它们。
答案 0 :(得分:0)
假设您对ft和ftrec正确,则可以尝试以下操作:
在顶部添加代码:
DROP TABLE IF EXISTS #ftrec
SELECT *
INTO #ftrec
FROM FinancialTransactions
where AssetID in (select AssetID from vAssetSimpleView where AssetID is not null)
CREATE CLUSTERED INDEX IX_ftrec on #ftrec(AssetID)
并替换
LEFT OUTER JOIN FinancialTransactions ft ON ft.FinancialTypeID = 9
AND ft.AssetID = a.AssetID
LEFT OUTER JOIN FinancialTransactions ftRec ON ftRec.AssetID = a.AssetID
使用
LEFT OUTER JOIN #ftrec ft ON ft.FinancialTypeID = 9
AND ft.AssetID = a.AssetID
LEFT OUTER JOIN #ftrec ftRec ON ftRec.AssetID = a.AssetID
这假设FinancialTransactions有点小。您可以仅用ftRec实际需要的列替换*。性能影响可能是在初始查询总数#ftrec上。这种解决方案可能是不可行的,如果上FinancialTransactions数据是巨大的。