【问题标题】:convert Image column is very slow转换图像列很慢
【发布时间】:2012-09-24 00:09:59
【问题描述】:

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

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

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

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

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

每次我执行转换包副本时,只有不存在数据(新数据)从旧数据库到新数据库。

我使用以下格式:

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

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

提前致谢。

【问题讨论】:

    标签: ssis lookup


    【解决方案1】:

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

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

    对于这项工作,不需要任何自定义代码或动态 SQL。您-确实-希望从数据流中的源系统获取 ID 和图像(除非您有主要的网络瓶颈需要解决)- 进行 RBAR 查找以从旧系统获取图像数据是一种非常落后的方式思考你的 ETL。

    【讨论】:

      【解决方案2】:
      1. 从源表中仅选择ID
      2. 在目标数据库中进行查找而不进行任何更改
      3. 对于它的no match output 在源表中进行查找,将Cache Mode 设置为No cache,这会将图像附加到流中。

      在这种情况下,每张图片都将单独获取,这可能会影响性能。

      【讨论】:

        【解决方案3】:

        您也可以在两个数据流中执行此操作。

        首先:

        1. 仅从源表中选择 ID
        2. 在目标数据库中进行查找而不进行任何更改
        3. 将新的Ids 存储在字符串变量IdListToBeFetched 中作为逗号分隔列表,使用Srcipt 组件作为目标女巫代码,类似于:
        
        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 中获取所有图像,这应该更快。

        ADO NET SourceODBC Source 等来源中将动态生成的查询设置为SqlCommand

        1. 选择包含您的源的Data Flow TaskExpression 属性
        2. 找到属性[your source name].[SqlCommand]并在此处设置表达式

        将动态生成的查询设置为OLE DB Source中的sql命令(取自Jamie Thomson blog):

        1. 创建一个名为 SourceSQL 的新变量
        2. 打开 SourceSQL 变量的属性窗格(按 F4)
        3. 设置 EvaluateAsExpression=TRUE
        4. Expression 设置为"select ID, Image from Attachment where ID in (" + @[User::IdListToBeFetched] + ")"
        5. 对于您的 OLE DB 源组件,打开编辑器
        6. 设置数据访问模式="来自变量的 SQL 命令"
        7. 设置变量名 = "SourceSQL"

        【讨论】:

          猜你喜欢
          • 2013-12-06
          • 1970-01-01
          • 1970-01-01
          • 2016-04-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-21
          相关资源
          最近更新 更多