调用 TVF 的存储过程怎么会比内联 TVF 的过程慢?
问题:
我有两个视图:
V_Room, 14969 rows, 9 tables joined together
V_parkings, 3265 rows, 9 tables joined together
然后我有一个视图
V_Rooms_UsageTypes with 18234 rows
,它是 V_Room 和 V_parkings 之间的并集
然后我有一个像这样的表值函数 函数
CREATE FUNCTION [dbo].[tfu_RPT_UsageTypesBySIADetail]
(@in_reporting_date datetime)
-- Add the parameters for the function here
RETURNS TABLE
连接 9 个表的 并在视图 V_Rooms_UsageTypes 上进行如下所示的 77 个子选择
(
SELECT
ISNULL(SUM(ZO_RMArea_Area), 0.0)
FROM dbo.V_Rooms_UsageTypes
WHERE V_Rooms_UsageTypes.FL_UID = T_Floor.FL_UID
AND (V_Rooms_UsageTypes.DIN277_Major = 9)
AND (V_Rooms_UsageTypes.DIN277_Minor = 4)
AND (V_Rooms_UsageTypes.ZO_RMUT_DateFrom <= @in_reporting_date)
AND (V_Rooms_UsageTypes.ZO_RMUT_DatumTo >= @in_reporting_date)
AND (V_Rooms_UsageTypes.ZO_RMArea_DateFrom <= @in_reporting_date)
AND (V_Rooms_UsageTypes.ZO_RMArea_DatumTo >= @in_reporting_date)
AND (V_Rooms_UsageTypes.RM_DateFrom <= @in_reporting_date)
AND (V_Rooms_UsageTypes.RM_DatumTo >= @in_reporting_date)
AND (V_Rooms_UsageTypes.SO_DateFrom <= @in_reporting_date)
AND (V_Rooms_UsageTypes.SO_DatumTo >= @in_reporting_date)
AND (V_Rooms_UsageTypes.BG_DateFrom <= @in_reporting_date)
AND (V_Rooms_UsageTypes.BG_DatumTo >= @in_reporting_date)
AND (V_Rooms_UsageTypes.FL_DateFrom <= @in_reporting_date)
AND (V_Rooms_UsageTypes.FL_DatumTo >= @in_reporting_date)
) AS RPT_VF_9_4
然后我有一个调用表值函数的存储过程 使用动态 SQL(因为报告服务的多种语言的列别名, 只需要一个一致的列名),
如下所示:
CREATE PROCEDURE [dbo].[sp_RPT_DATA_AreaByDIN277_old]
@in_customer varchar(3),
@in_language varchar(2),
@in_site varchar(36),
@in_building varchar(36),
@in_floor varchar(36),
@in_reporting_date varchar(50)
AS
DECLARE
@sql varchar(8000),
@reporting_date datetime
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
SET @reporting_date= CONVERT( DATETIME, @in_reporting_date )
SET @reporting_date= Cast(Floor(Cast(@reporting_date As Float)) As DateTime)
SET @in_reporting_date= CONVERT(varchar(50), @reporting_date )
SET NOCOUNT ON;
SET @sql='SELECT
FIELD_1_' + @in_language +' AS RPT_FIELD_1
,FIELD_2_' + @in_language +' AS RPT_FIELD_2
,FIELD_3 AS RPT_FIELD_3
,table_valued_function_column1 AS RPT_table_valued_function_column1
,table_valued_function_column2 AS RPT_table_valued_function_column2
,table_valued_function_columnN AS RPT_table_valued_function_columnN
'
SET @sql=@sql + 'FROM dbo.tfu_RPT_FM_NutzungsartenNachSIADetail(''' + @in_reporting_date + ''') '
SET @sql=@sql + 'WHERE ST_Customer = ''' + @in_customer + ''' '
IF @in_site <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (ST_UID = ''' + @in_site + ''') '
IF @in_building <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (BG_UID = ''' + @in_building + ''') '
IF @in_floor <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (FL_UID = ''' + @in_floor + ''') '
EXECUTE (@sql)
现在,正如预期的那样,查询需要相当长的时间(20 秒)才能返回结果。 所以我将整个表值函数移到动态sql存储过程中 并且执行速度大约为一半(10 秒)。
相反,我的执行时间为 30 秒。 这是为什么呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
与单独优化 TVF 相比,引擎很可能能够更好地处理它,而 TVF 只是更大查询的一部分。此外,动态 SQL 可能会改变计划的缓存方式。您忘记提及您正在使用的 SQL Server 版本,但是您是否使用过“优化临时工作负载"设置,或
优化未知
?It's quite possible that the engine can better deal with optimizing the TVF separately than when it's just part of a much larger query. Also the dynamic SQL may change the way the plans are cached. You forgot to mention which version of SQL Server you're using, but have you played with the "optimize for ad hoc workloads" setting, or
OPTIMIZE FOR UNKNOWN
??