在下面的帖子中,JD 提出我有一个性能不佳的查询。
我在 SQL Server 2019 标准版上运行此查询(查询计划是在开发版中生成的)
让我们在这里看一下:
INSERT INTO [dbo].[tbl_Planning_Operational_Data_Exploded] (
[ScenarioID]
,[CompanyID]
,[OperationalAccountID]
,[CurrencyID]
,[CustomerID]
,[ItemID]
,[CalendarDate]
,[Amt]
,[PlanningOperationalDataActualTransactionAttributeValueExplodedID]
)
SELECT ats.[ScenarioID]
,pode.[CompanyID]
,pode.[OperationalAccountID]
,pode.[CurrencyID]
,pode.[CustomerID]
,pode.[ItemID]
,pode.[CalendarDate]
,SUM(pode.[Amt]) AS Amt
,'00000000-0000-0000-0000-000000000000' AS [PlanningOperationalDataActualTransactionAttributeValueExplodedID]
FROM #ActualThroughScenarios ats WITH (NOLOCK) --Mini 100 records
INNER JOIN [dbo].[tbl_Core_Scenarios] cs WITH (NOLOCK) ON cs.ScenarioID = ats.ScenarioID --Mini 100 records
AND cs.ScenarioTypeID IN (
2
,3
)
INNER JOIN [dbo].[tbl_Core_Scenarios] csActuals WITH (NOLOCK) ON csActuals.FiscalYear = cs.FiscalYear --Mini 100 records
AND csActuals.ScenarioTypeID = 1
INNER JOIN [dbo].[tbl_Planning_Operational_Data_Exploded] pode ON pode.ScenarioID = csActuals.ScenarioID -- Huge up to 300 million records
INNER JOIN [dbo].[tbl_Core_Fiscal_Date] cfd WITH (NOLOCK) ON pode.CalendarDate = cfd.CalendarDate --Mini 1000 records
WHERE cfd.FiscalPeriod <= cs.ActualsThrough
AND cs.ActualsThrough > 0
GROUP BY ats.[ScenarioID]
,pode.[CompanyID]
,pode.[OperationalAccountID]
,pode.[CurrencyID]
,pode.[CustomerID]
,pode.[ItemID]
,pode.[CalendarDate]
查询计划生成:https://www.brentozar.com/pastetheplan/? id=Sk69AQ-As
基本上这个查询非常简单,我有一个非常大的表“Exploded”,我需要对其进行分段,对它们进行分组并修改“ScenarioID”,然后将它们重新插入到同一个表中。
我可以优化或转移所有小表的索引策略,但在数据库的其他部分(未显示有很多)向“Exploded”表添加索引非常昂贵,我宁愿不添加任何额外的索引那张桌子
正如在上面的链接帖子中提到的,这个查询可以运行可以运行得非常慢,因为它会生成一个非常大的哈希匹配,我认为这是通过这样做的组,但我需要组依据,那个和求和是什么的关键部分我在这里做:
这会溢出到 TempDB 并受 TempDB 速度的严重影响。鉴于我对相关表的约束,有什么方法可以改进上面的查询吗?