sql - 何时在 SQL Server 数据仓库中使用用户定义的函数

标签 sql sql-server ssis etl data-warehouse

我正在创建一个 DWH,在其中将数据加载到临时数据库中,并在将它们加载到最终数据库之前应用我在数据上创建的所有 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;

最佳答案

首先,正如 @Nick.McDermaid 在评论中提到的:最佳实践是避免使用用户定义的函数。有许多链接包含有关函数对查询性能影响的信息。


这些问题没有理想的答案,这与您正在处理的案例有关,但我可以提供一些您可以考虑的提示:

  • 首先,如果您使用 SSIS 将数据导入到临时表中,请尝试使用 SSIS 数据流组件(例如派生列转换、查找)替换用户定义的函数,这样可以增强数据导入的性能。
  • 如果无法用 SSIS 组件替换 UDF:如果您正在高速收集数据到数据湖(暂存级别),然后在需要时加载数据,则在将数据导入到暂存表时最好避免使用函数.
  • 如果您需要保证从临时表加载数据时的高速性,请在第一个数据导入阶段使用该功能。
  • 如果第一个数据导入阶段(到临时表)和第二个阶段(从临时表)不是在同一台计算机上执行,则最好在性能更高的计算机上执行函数。
  • 如果函数包含一些查找等操作,请尝试用连接替换它们。

...

更新 1

在问题中发布函数后,您可以将函数 2 替换为 SSIS 包中的派生列转换:

ISNULL([Column]) ? "" : REPLACE(REPLACE(REPLACE(REPLACE([Column],CHAR(10),""),CHAR(13),""),CHAR(09),""),CHAR(34),CHAR(39))

您还可以将函数 1 替换为 SSIS 包中的查找转换或 SQL 查询中的 LEFT JOIN。

关于sql - 何时在 SQL Server 数据仓库中使用用户定义的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54282348/

相关文章:

sql-server - 根据字段值在ssis中拆分行

mysql - 如何检索没有具有特定值的子对象的父对象? Sequelize

sql - 将标识列从 int 替换为 bigint

sql - 使用 Cross Join 时的 Group By 语法

sql-server - TSQL 电子邮件验证(无正则表达式)

sql-server - 在SSIS中使用对象数据类型变量作为表名进行查询

sql - 是否有更有效的方法来执行此 SQL 选择?

java - quartz scheduler.2.2x 创建 sql server 数据库模式?

sql-server - 当涉及多个聚合时, 'Worktable' 的读取计数异常巨大

sql-server - 从头开始构建 OLAP 解决方案时应该注意什么?