如何优化SQL Server查询?这是我想要优化的代码
CREATE TABLE #Temp
(
TransactionId int PRIMARY KEY,
TransactionStepId int
)
INSERT INTO #Temp(TransactionId, TransactionStepId)
SELECT
TransactionId, MAX(TransactionStepId) TransactionStepId
FROM
[WarehouseMgmt].[FactPaymentTrans] FPT
JOIN
WarehouseMgmt.DimTimeZone DTZ on FPT.[TimeId] = DTZ.TimeUTCId
WHERE
FactType = 'SOURCE'
AND (DTZ.TimeId BETWEEN @DimStartDate AND @DimEndDate)
GROUP BY
TransactionId
IF(UPPER(@ReportBy) = 'TRANSACTION')
BEGIN
SET @sql = '
INSERT INTO #Results (
[PaymentTypeId],
[TransactionDate],
[PaymentMethodId],
[3DSecureId],
[ProductId],
[ProductTypeId],
[TransactionStatusId],
[Amount],
[Currency],
[PlayerId],
[PlayerSourceOrigId],
[Username],
[FirstName],
[LastName],
[BrandId],
[VIPLevelId],
[MarketingChannelId],
[MarketingSourceId],
[CommentId],
[CommentRefId],
[AdminName],
[OriginalTransactionId],
[TransactionId],
[RelatedTransactionId],
[ProviderTransactionOrigId]
)
SELECT
DTST.[Id],
FPT.[StartTime],
FPT.[PaymentMethodId],
FPT.[3DSecureId],
FPT.[ProductId],
DPT.[Id],
FPT.[TransactionStatusId],
FPT.[Amount],
FPT.CurrencyId,
FPT.[PlayerId],
DPL.[SourceOrigId],
DPL.[Username],
DPL.[FirstName],
DPL.[LastName],
DPL.[BrandId],
DPL.[VIPLevelId],
DPL.[MarketingChannelId],
DPL.[MarketingSourceId],
FPT.[PaymentReasonTextId],
FPT_Ref.[PaymentReasonTextId],
FPT.CreatedByAdminId,
FPT.[OriginalTransactionId],
FPT.[TransactionId],
FPT_Ref.[OriginalTransactionId],
FPT.[ProviderTransactionOrigId]
FROM WarehouseMgmt.FactPaymentTrans AS FPT
JOIN #Temp T ON FPT.TransactionId = T.TransactionId AND FPT.TransactionStepId = T.TransactionStepId
JOIN WarehouseMgmt.DimTransactionStepType AS DTST ON FPT.[TransactionStepTypeId] = DTST.[Id]
JOIN WarehouseMgmt.DimPlayer AS DPL ON FPT.PlayerId = DPL.Id
JOIN WarehouseMgmt.DimProduct AS DP ON DP.Id = FPT.ProductId
JOIN WarehouseMgmt.DimProductType AS DPT ON DPT.Id = DP.ProductTypeId
--JOIN WarehouseMgmt.DimTimeZone DTZ on FPT.[TimeId] = DTZ.TimeUTCId
JOIN [WarehouseMgmt].[DimLoyaltyProgramLevel] DLPL ON DLPL.[Id]=DPL.VipLevelId
LEFT JOIN
(
SELECT FPT_Ref_1.TransactionId,FPT_Ref_1.FactType,FPT_Ref_1.OriginalTransactionId,FPT_Ref_1.[PaymentReasonTextId]
FROM WarehouseMgmt.FactPaymentTrans AS FPT_Ref_1
JOIN #Temp T ON T.TransactionId = FPT_Ref_1.OriginalTransactionId AND T.TransactionStepId = FPT_Ref_1.TransactionStepId
) AS FPT_Ref ON FPT_Ref.OriginalTransactionId = FPT.TransactionId AND FPT_Ref.FactType = ''SOURCE''
WHERE (FPT.FactType = ''SOURCE'') ' + @sqlFilters
我试着把这个
SELECT TransactionId,MAX(TransactionStepId) TransactionStepId
FROM [WarehouseMgmt].[FactPaymentTrans]
WHERE FactType = ''SOURCE''
GROUP BY TransactionId
临时表中的,但如果没有临时表,这甚至是最差的。我想选择最新的TransactionId(由MAX(TransactionStepId)制作,也可以选择左边的最后一个TransactionId
我的执行计划是:
答案 0 :(得分:1)
您是否考虑过使用ROW_NUMBER而不是两次加入您的桌子?请试试这个:
;WITH FactPaymentTrans_Last
AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY TransactionID ORDER BY TransactionStepID DESC) AS RN
FROM WarehouseMgmt.FactPaymentTrans
)
SELECT DTST.[Id]
, FPT.[StartTime]
, FPT.[PaymentMethodId]
, FPT.[3DSecureId]
, FPT.[ProductId]
, DPT.[Id]
, FPT.[TransactionStatusId]
, FPT.[Amount]
, FPT.CurrencyId
, FPT.[PlayerId]
, DPL.[SourceOrigId]
, DPL.[Username]
, DPL.[FirstName]
, DPL.[LastName]
, DPL.[BrandId]
, DPL.[VIPLevelId]
, DPL.[MarketingChannelId]
, DPL.[MarketingSourceId]
, FPT.[PaymentReasonTextId]
, FPT_Ref.[PaymentReasonTextId]
, FPT.CreatedByAdminId
, FPT.[OriginalTransactionId]
, FPT.[TransactionId]
, FPT_Ref.[OriginalTransactionId]
, FPT.[ProviderTransactionOrigId]
FROM FactPaymentTrans_Last AS FPT
INNER JOIN WarehouseMgmt.DimTransactionStepType AS DTST
ON FPT.[TransactionStepTypeId] = DTST.[Id]
INNER JOIN WarehouseMgmt.DimPlayer AS DPL
ON FPT.PlayerId = DPL.Id
INNER JOIN WarehouseMgmt.DimProduct AS DP
ON DP.Id = FPT.ProductId
WHERE FPT.RN = 1;
这只是一个片段,可以让您了解如何根据TransactionIds
使用此内容获取最新TransactionStepId
。
如果还不够 - 请发布以下内容:
这将有助于为您提供建议。
答案 1 :(得分:1)
有多个因素可以提高查询性能,其中一个可以完成,而不必了解有关索引,数据库架构,数据分布等的详细信息,这是查询中JOIN
s的顺序。
我已经重构了你的查询,我认为你应该得到与以前相同的结果,但是执行时间有所改善:
SELECT DTST.[Id]
,FPT.[StartTime]
,FPT.[PaymentMethodId]
,FPT.[3DSecureId]
,FPT.[ProductId]
,DPT.[Id]
,FPT.[TransactionStatusId]
,FPT.[Amount]
,FPT.CurrencyId
,FPT.[PlayerId]
,DPL.[SourceOrigId]
,DPL.[Username]
,DPL.[FirstName]
,DPL.[LastName]
,DPL.[BrandId]
,DPL.[VIPLevelId]
,DPL.[MarketingChannelId]
,DPL.[MarketingSourceId]
,FPT.[PaymentReasonTextId]
,FPT_Ref.[PaymentReasonTextId]
,FPT.CreatedByAdminId
,FPT.[OriginalTransactionId]
,FPT.[TransactionId]
,FPT_Ref.[OriginalTransactionId]
,FPT.[ProviderTransactionOrigId]
FROM WarehouseMgmt.FactPaymentTrans AS FPT
INNER JOIN WarehouseMgmt.DimPlayer AS DPL
ON FPT.PlayerId = DPL.Id
INNER JOIN WarehouseMgmt.DimProduct AS DP
ON DP.Id = FPT.ProductId
INNER JOIN WarehouseMgmt.DimProductType AS DPT
ON DPT.Id = DP.ProductTypeId
INNER JOIN WarehouseMgmt.DimTransactionStepType AS DTST
ON FPT.[TransactionStepTypeId] = DTST.[Id]
WHERE (FPT.FactType = '' SOURCE '')
AND EXISTS (SELECT 1
FROM [WarehouseMgmt].[FactPaymentTrans]
WHERE FactType = '' SOURCE ''
AND FPT.TransactionId = TransactionId
AND FPT.TransactionStepId = TransactionStepId)
AND EXISTS (SELECT 1
FROM [WarehouseMgmt].[DimLoyaltyProgramLevel] DLPL
WHERE DLPL.[Id] = DPL.VipLevelId)
AND EXISTS (SELECT 1
FROM WarehouseMgmt.DimTimeZone DTZ
WHERE FPT.[TimeId] = DTZ.TimeUTCId
AND DTZ.TimeId BETWEEN @DimStartDate AND @DimEndDate)