我正在尝试加快查询速度。我需要每行运行2个标量值函数,并使用几列作为参数。
这些函数基于运行总计进行计算,并且在SQL Server 2008中没有简单的方法(据我所知)执行此操作。
查询的CTE部分获取了我需要进行计算的所有行,并且需要针对每个级别分别运行。客户端与商店的关系是一对多的,但是您无法基于其每个商店计算在客户端级别(Store ='All')进行计算。
我的第一个尝试是将函数调用包含在“ SELECT”语句中,但我读到它们将同步运行,这是不必要的。下面的尝试是试图将计算转换为表值,以尝试异步运行它们。
我想知道是否应该使用OUTER APPLY,或者是否有更有效的方法来解决这个问题。
让我知道是否需要更多信息!
DECLARE @StartTime INT
SET @StartTime=20170101
DECLARE @EndTime INT
SET @EndTime=20170131
;WITH IsAvgStores AS (
SELECT
COALESCE(ParentClient,'All') AS ParentClient,
COALESCE(Client,'All') AS Client,
COALESCE(Store,'All') AS Store,
MAX(Answer_Threshold),
MAX(SL_Threshold)
FROM
client_hierarchy
WHERE
GETDATE() BETWEEN EFF_BEGIN_DATE AND EFF_END_DATE
GROUP BY ROLLUP(ParentClient,Client,Store)
)
SELECT I.ParentClient,I.Client,I.Store
,SL.isAvg_SL_String
,A.isAvg_ASA_String
INTO #isAvgTemp
FROM IsAvgStores I
OUTER APPLY ( SELECT dbo.isAvg_S_B(ParentClient,Client,Store,Answer_Threshold,@StartTime,@EndTime) AS isAvg_SL_String
) SL
OUTER APPLY ( SELECT dbo.isAvg_A_B(ParentClient,Client,Store,SL_Threshold,@StartTime,@EndTime) AS isAvg_ASA_String
) A
WHERE ParentClient<>'All'
SELECT *
FROM #isAvgTemp
最佳答案
这个评论太长了。outer apply
对于标量值函数是多余的。您可以这样做:
SELECT I.ParentClient, I.Client, I.Store,
dbo.isAvg_S_B(ParentClient, Client, Store,A nswer_Threshold, @StartTime, @EndTime) AS isAvg_SL_String,
dbo.isAvg_A_B(ParentClient, Client, Store, SL_Threshold, @StartTime, @EndTime) as isAvg_ASA_String
INTO #isAvgTemp
FROM IsAvgStores I
WHERE ParentClient <> 'All';
这绝对不会影响性能。它只是简化了查询。
为了提高性能,您有三个选择:
重写代码以删除功能;使用
outer apply
作为运行总和。重写代码以删除功能;使用递归CTE作为运行总和。
重写代码以删除功能;使用游标作为运行总和。
这些都不是最优的。如果单个组很小,则前两个可能会起作用。在这种情况下,第三个可能是最好的选择-请注意,我非常讨厌光标。
或者,最好的选择是:升级到更高版本的SQL Server,并使用SQL Server 2012+中提供的累积总和功能。