转换Image列非常慢

时间:2012-09-22 09:34:12

标签: ssis lookup

我想将旧数据库中的数据转换为具有新结构的新数据库。 在旧数据库中,我有附件表,必须转换为新数据库中的附件表。

旧的数据库附件表结构如下:

Attachment (ID int, Image Image, ...)

和新的数据库附件表结构如下:

Attachment (ID int, Image Image, OldID Int, ...)

每次执行转换包复制时,不存在从旧数据库到新数据库的数据(新数据)。

我使用以下格式来执行此操作:

enter image description here

在旧表和新表(ID --> OldID)之间进行查找以检查存在记录。

当我运行SSIS包时; SSIS,首先在内存中缓存所有查找和源组件数据,然后执行包。我在这个包中的源数据是非常庞大的,当我运行这个包时,它将运行得非常慢。我希望在lookup for check exists组件之后为每个新记录从旧数据库中获取Image列数据。如果我使用新的查找组件从旧数据库获取图像列数据,SSIS缓存这个新的查找数据和运行此包的执行时间不会改变。我该怎么办?

提前感谢。

3 个答案:

答案 0 :(得分:0)

  1. 仅从源表
  2. 中选择ID
  3. 在目标数据库中查找而无需更改
  4. 对于no match output在源表中执行查找,将Cache Mode设置为No cache,这会将Image附加到流中。
  5. 在这种情况下,将分别提取每个图像,这可能会影响性能。

答案 1 :(得分:0)

您也可以在两个数据流中完成。

首先:

  1. 仅从源表
  2. 中选择ID
  3. 在目标数据库中查找而无需更改
  4. 使用Srcipt Component作为逗号分隔列表,将新Ids存储在字符串变量IdListToBeFetched中作为目标代码,类似于:
  5. 
    using System.Text;
    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {
        StringBuilder sb;
        public override void PreExecute()
        {
            base.PreExecute();
            sb = new StringBuilder();
        }
    
        public override void PostExecute()
        {
            base.PostExecute();
            Variables.IdListToBeFetched = sb.ToString().TrimEnd(',');
        }
    
        public override void Input0_ProcessInputRow(Input0Buffer Row)
        {
            if (!Row.ID_IsNull)
            {
                sb.AppendFormat("{0},", Row.ID);
            }
        }
    }
    

    在第二个数据流中设置sql命令源为动态生成的查询,其表达式类似于"select ID, Image from Attachment where ID in (" + @[User::IdListToBeFetched] + ")"并设置DelayValidation = True。单个select中的所有图像都应该更快。

    SqlCommandADO NET Source等来源中将动态生成的查询设为ODBC Source

    1. 选择包含您的来源的Expression的{​​{1}}属性
    2. 找到属性Data Flow Task并在此处设置表达式
    3. 将动态生成的查询设置为[your source name].[SqlCommand]中的sql命令(取自Jamie Thomson blog):

      1. 创建一个名为SourceSQL的新变量
      2. 打开SourceSQL变量的属性窗格(按F4键)
      3. 设置EvaluateAsExpression = TRUE
      4. OLE DB Source设为Expression
      5. 对于您的OLE DB Source组件,打开编辑器
      6. 设置数据访问模式=“来自变量的SQL命令”
      7. 设置VariableName =“SourceSQL”

答案 2 :(得分:0)

你确定你正确地想到了吗?即使您加载的数据量很大,SSIS也不应该很慢。

你的LOOKUP组件需要确保它没有做任何不需要的事情。如果要将其指向新数据库中的表,请立即将其更改为SQL查询。在此查询中,您只需要SELECT OldId FROM tbl并将旧数据库中的传入ID指向此。您的数据流应包含来自旧数据库的ID和图像,它在您的OLE DB目标中映射ID -> OldId和“图像 - >图像”。不再需要“仅插入新行”操作,就像您正在做的那样这里。

对于此作业,不需要任何自定义代码或动态SQL。您希望从数据流中的源系统获取ID和映像(除非您有主要的网络瓶颈要进行整理) - 执行RBAR查找以从旧系统获取映像数据是一种非常倒退的方式想着你的ETL。