【发布时间】:2019-01-21 00:55:26
【问题描述】:
我正在创建一个 DWH,我正在将数据加载到 Staging DB 中,在将它们加载到最终 DB 之前,我会应用我在数据上创建的所有 udf。
- 源数据库:Oracle
- 目标数据库:SQL Server
- ETL 过程:SSIS 包
我没有在暂存时处理任何东西来快速加载。
问题:当数据处于暂存状态时应用任何 udf 是否更快,或者是否应该在将数据加载到最终数据库时完成。
facility_cd 下面是一个float 值,我将它传递给函数emr_get_code_Description 以获取相应的描述。从中获取描述的表位于最终数据库中。 udf_replace_special_char 是一个简单的函数,它将一些特殊字符替换为 NULL。
LTRIM(RTRIM([Dest_DWH].[dbo].udf_replace_special_char([Dest_DWH].[dbo].[emr_get_code_Description](Stg_ap.Facility_cd))))
一般来说,更好的做法应该是什么?我是否应该在暂存中更新它,然后在所有转换到最终数据库后加载数据。
函数定义:
功能 1:
USE [PROD_DWH]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[emr_get_code_Description](@cv int)
returns varchar(80)
as begin
-- Returns the code value display
declare @ret varchar(80)
select @ret = cv.DESCRIPTION
from PROD_DWH.DBO.table cv
where cv.code_value = @cv
and cv.active_ind = 1
return isnull(@ret, 0)
end;
功能2:
USE [PROD_DWH]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[udf_replace_special_char](@var varchar(1000))
returns varchar(1000)
as begin
-- Returns the code value display
declare @return_var varchar(1000)
set @return_var = @var
set @return_var = replace(@return_var,CHAR(13),'')
set @return_var = replace(@return_var,CHAR(10),'')
set @return_var = replace(@return_var,CHAR(09),'')
set @return_var = replace(@return_var,CHAR(34),CHAR(39))
return isnull(@return_var, 0)
end;
【问题讨论】:
-
我猜从 staging 到 final 但实际上这完全取决于很多变量,我只是测试两者来找出你的答案。
-
最佳实践是根本不使用 UDF,因为它们有可能引入性能问题。我还要说,最好的做法是在 staging 之前完全准备好数据,然后确保从 staging 到 dw 的负载尽可能快,以减少报告影响。即对事务使用分区切换和/或快照隔离
-
我完全同意你的看法,尼克。引入一个函数后需要一小时,现在添加第二个函数后需要 2.5 小时。我可以通过替换语句删除 udf_replace_special_char。但另一个函数实际上是包含一个选择语句。我在最初的问题中添加了函数定义。
-
函数 emr_get_code_Description 在单个表加载中被使用了近 20 次。我在某处读到表值函数提供更好的性能,但在这种情况下,不可能使用它们,因为我需要在存储过程中多次使用该函数。关于如何用其他东西替换这些功能的任何建议都会很棒。 @哈迪
-
@Doodle 正如我在回答中提到的,您可以在主查询中将其替换为 Join
标签: sql sql-server ssis etl data-warehouse