0

我在 SSIS 2008 中有一个数据流任务,它使用 OLE DB 源提取大约 2,000,000 行,然后通过 24 次查找转换将“代码”数据逐一替换为维度表中的预定义等效数据,或者“未知”值。

这个一个接一个的过程,整个流程贯穿每个转换,已经成为包执行的主要瓶颈,我需要一种方法来加快这个过程。有任何想法吗?

我尝试将数据集多播到 24 个不同的查找中的每一个(以便仅将必要的列发送给它)但是当我将它们全部运行到一个联合中时,所有任务似乎都不喜欢各种数据类型和无论我如何配置它,都会引发错误。我还有另一个选择吗?

4

2 回答 2

2

我会在纯 TSQL 中完成这一切:将 200 万行插入到临时表中,并使用 UPDATE 语句来设置您需要的值。这几乎肯定会比逐行查找过程快得多,并且您还可以在必要时将索引放在临时表上。

数据更新后,您可以将其推送到另一个数据流中的目标表,或者,如果暂存表和目标表在同一台服务器上,则只需使用INSERT ... SELECT ...即可。

就个人而言,如果在 TSQL 中有一种简单的方法,我总是避免使用 SSIS 转换;性能更好,我发现 TSQL 代码比 SSIS 包更易于维护。话虽如此,SSIS 是一个出色的控制流工具,用于从不同位置获取数据,将其传送到暂存数据库,您可以在其中对其进行处理,并执行过程或脚本来转换数据。

于 2011-07-11T07:43:44.687 回答
0

瓶颈可能不在你认为的地方。它可能是降低包性能的目标组件。包转换等到批处理数据插入目标。这使我们相信以黄色显示的转换正在缓慢执行。实际上,就我的经验而言,查找转换任务非常快。

以下示例从平面文件源读取 100 万行并插入 SQL Server。尽管它只使用一个查找,但我在这里提供示例的原因是为了让您了解拥有多个目标组件。拥有多个目的地来接受各种转换处理的数据将加快打包速度。

我希望这个例子能让你了解如何提高你的包性能。

分步过程:

  1. 在 SQL Server 数据库中,创建两个表,即dbo.ItemInfodbo.Staging脚本部分下提供了创建表查询。这些表的结构显示在屏幕截图 # 1中。ItemInfo将保存实际数据,Staging表将保存暂存数据以比较和更新实际记录。Id这两个表中的列都是自动生成的唯一标识列。IsProcessed表 ItemInfo 中的列将用于识别和删除不再有效的记录。

  2. 创建一个 SSIS 包并创建5 个变量,如屏幕截图 # 2所示。我.txt为制表符分隔的文件使用了扩展名,因此使用*.txt了变量FileExtension中的值。FilePath变量将在运行时赋值。FolderLocation变量表示文件的位置。变量表示在预加载和加载后操作期间使用的存储过程SQLPostLoadSQLPreLoad这些存储过程的脚本在脚本部分提供。

  3. 创建一个指向 SQL Server 数据库的 OLE DB 连接。创建一个平面文件连接,如屏幕截图 # 3和 # 4所示。平面文件连接列部分包含列级别信息。屏幕截图# 5显示了列数据预览。

  4. 如屏幕截图# 6所示配置控制流任务。配置任务Pre Load,如截图# Post Load7- # 10所示。Pre Load 将截断临时表并将ItemInfo 表中所有行的标志设置为 false。Post Load 将更新更改并删除数据库中未在文件中找到的行。请参阅这些任务中使用的存储过程,以了解这些任务中正在执行的操作。Loop FilesIsProcessedExecute SQL

  5. 双击 Load Items 数据流任务并对其进行配置,如屏幕截图 # 11所示。Read File是配置为使用平面文件连接的平面文件源。Row Count是派生列转换,其配置显示在 screenshto # 12中。Check Exist是一个查找转换,其配置显示在屏幕截图 # 13 - # 15中。查找无匹配输出重定向到Destination Split左侧。查找匹配输出重定向到Staging Split左侧。Destination Split并具有与屏幕截图 # 16Staging Split中所示完全相同的配置. 目的地和临时表有 9 个不同目的地的原因是为了提高包的性能。

  6. 所有目标任务 0-8 都配置为将数据插入表dbo.ItemInfo中,如屏幕截图 # 17所示。所有 staging 任务 0-8 都配置为插入数据dbo.Staging,如屏幕截图 # 18所示。

  7. 在平面文件连接管理器上,将 ConnectionString 属性设置为使用变量 FilePath,如屏幕截图 # 19所示。这将使包在遍历文件夹中的每个文件时能够使用变量中设置的值。

测试场景:

Test results may vary from machine to machine. 
In this scenario, file was located locally on the machine. 
Files on network might perform slower. 
This is provided just to give you an idea. 
So, please take these results with grain of salt.
  1. 包在具有 Xeon 单核 CPU 2.5GHz 和 3.00 GB RAM 的 64 位机器上执行。

  2. 加载了一个带有1 million rows. 包在大约2 分 47 秒内执行。请参阅屏幕截图# 20和# 21

  3. 使用测试查询部分下提供的查询来修改数据,以在包的第二次运行期间模拟更新、删除和创建新记录。

  4. 1 million rows在数据库中执行以下查询后,加载包含以下查询的相同文件。包在大约1 分 35 秒内执行。请参阅屏幕截图# 22和# 23请注意屏幕截图 # 22中重定向到目标和临时表的行数。

希望有帮助。

测试查询: .

--These records will be deleted during next run 
--because item ids won't match with file data.
--(111111 row(s) affected)
UPDATE dbo.ItemInfo SET ItemId = 'DEL_' + ItemId WHERE Id % 9 IN (3)

--These records will be modified to their original item type of 'General'
--because that is the data present in the file.
--(222222 row(s) affected)
UPDATE dbo.ItemInfo SET ItemType = 'Testing' + ItemId WHERE Id % 9 IN (2,6)

--These records will be reloaded into the table from the file.
--(111111 row(s) affected)
DELETE FROM dbo.ItemInfo WHERE Id % 9 IN (5,9)

平面文件连接列

Name        InputColumnWidth     DataType          OutputColumnWidth
----------  ----------------     ---------------   -----------------
Id          8                    string [DT_STR]   8
ItemId      11                   string [DT_STR]   11
ItemName    21                   string [DT_STR]   21
ItemType    9                    string [DT_STR]   9

脚本:( 创建表和存储过程)

CREATE TABLE [dbo].[ItemInfo](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ItemId] [varchar](255) NOT NULL,
    [ItemName] [varchar](255) NOT NULL,
    [ItemType] [varchar](255) NOT NULL,
    [IsProcessed] [bit] NULL,
    CONSTRAINT [PK_ItemInfo] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [UK_ItemInfo_ItemId] UNIQUE NONCLUSTERED ([ItemId] ASC)) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Staging](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ItemId] [varchar](255) NOT NULL,
    [ItemName] [varchar](255) NOT NULL,
    [ItemType] [varchar](255) NOT NULL,
 CONSTRAINT [PK_Staging] PRIMARY KEY CLUSTERED ([Id] ASC)) ON [PRIMARY]
GO

CREATE PROCEDURE [dbo].[PostLoad]
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE      ITM
    SET         ITM.ItemName    = STG.ItemName
            ,   ITM.ItemType    = STG.ItemType 
            ,   ITM.IsProcessed = 1
    FROM        dbo.ItemInfo    ITM
    INNER JOIN  dbo.Staging     STG
    ON          ITM.ItemId      = STG.ItemId;

    DELETE FROM dbo.ItemInfo
    WHERE       IsProcessed = 0;
END
GO

CREATE PROCEDURE [dbo].[PreLoad]
AS
BEGIN
    SET NOCOUNT ON;

    TRUNCATE TABLE dbo.Staging;     

    UPDATE  dbo.ItemInfo 
    SET     IsProcessed = 0;
END
GO

截图#1:

1

截图#2:

2

截图#3:

3

截图#4:

4

截图#5:

5

截图#6:

6

截图#7:

7

截图#8:

8

截图#9:

9

截图#10:

10

截图 #11:

11

截图#12:

12

截图#13:

13

截图#14:

14

截图#15:

15

截图#16:

16

截图#17:

17

截图#18:

18

截图#19:

19

截图#20:

20

截图#21:

21

截图#22:

22

截图#23:

23

于 2011-07-12T07:22:18.160 回答