开篇介绍

先简单的演示一下使用 Lookup 组件实现一个简单示例 - 从数据源表 A 中导出数据到目标数据表 B,如果 A 数据在 B 中不存在就插入新数据到B,如果存在就更新B 和 A 表数据保持统一。

随后再来解释在这个过程中使用到的一些术语,以及分析一下 Lookup 中出现的几种缓存模式,各自的特点以及常用的场合。

案例讲解

两张表,一张是目标表 DEMO_LK_Customer,一张是 DEMO_LK_LegacyCustomer  旧系统表。我们可以理解我们这个示例要实现的目标是 DEMO_LK_Customer 表的数据要和DEMO_LK_LegacyCustomer 实现同步,保持一致。

USE BIWORK_SSIS
GO-- Look up demo table
IF OBJECT_ID('DEMO_LK_Customer','U') IS NOT NULL
DROP TABLE DEMO_LK_Customer
GOIF OBJECT_ID('DEMO_LK_LegacyCustomer','U') IS NOT NULL
DROP TABLE DEMO_LK_LegacyCustomer
GOCREATE TABLE DEMO_LK_Customer
(CustomerID INT PRIMARY KEY, CustomerCompany NVARCHAR(255), CustomerName NVARCHAR(20),CustomerAddress NVARCHAR(255)
)CREATE TABLE DEMO_LK_LegacyCustomer
(CustomerID INT PRIMARY KEY, CustomerCompany NVARCHAR(255), ContactName NVARCHAR(20),ContactTitle NVARCHAR(50),CustomerAddress NVARCHAR(255)
)INSERT INTO DEMO_LK_Customer VALUES
(1,'HFBZG','Allen,Michael','Obere Str. 0123'),
(2,'MLTDN','Hassall, Mark','Avda. de la Constitución 5678'),
(3,'KBUDE','Peoples, John','Mataderos  1000')INSERT INTO DEMO_LK_LegacyCustomer VALUES
(1,'NRZBB','Allen,Michael','Sales Representative','Obere Str. 0123'),
(2,'MLTDN','Hassall, Mark','Owner','Avda. de la Constitución 5678'),
(3,'KBUDE','Peoples, John','Owner','Mataderos  7890'),
(4,'HFBZG','Arndt, Torsten','Sales Representative','7890 Hanover Sq.'),
(5,'HGVLZ','Higginbotham, Tom','Order Administrator','Berguvsvägen  5678')SELECT * FROM DEMO_LK_Customer
SELECT * FROM DEMO_LK_LegacyCustomer--UPDATE DEMO_LK_Customer SET CustomerName = ?, CustomerCompany = ?, CustomerAddress = ? WHERE CustomerID = ?--UPDATE DEMO_LK_Customer SET CustomerName = ? WHERE CustomerID = ?--UPDATE DEMO_LK_Customer SET CustomerAddress = ? WHERE CustomerID = ?

在测试数据中,我们认为两张表的 ID 都是不变的唯一的,第1条数据和第3条数据不一致,第4条和第5条数据在目标表中不存在。

先看一下实现这个例子的 SSIS Package 结构,最外面的是一个数据流 DF_Lookup。

在数据流中,数据源 OLE_SRC_LegacyCustomer 在这个例子中使用的是 SQL Server 数据库表,但是这个数据源也可以是文本文件,Excel 或者其它数据库的表或者查询的结果集。

这个数据源相对于 Lookup 组件 LKP_Customer 来说是 Lookup 组件的输入项。

LKP_Customer 之后有两个分支 - 匹配和不匹配分支,做的事情就是匹配的数据做更新,不匹配的数据做插入动作。

输入源 OLE_SRC_LegacyCustomer 的配置

输入源中要向下输出的列 - 相对于 Lookup 组件,它的输出是 Lookup 的输入。

LKP_Customer 的缓存模式选择的是默认模式 - Full Cache 完全缓存,连接类型 OLE DB Connection 。

从上一个组件中输出的列即这里的数据源 Input 要到下面展示的表或者视图 DEMO_LK_Customer 中查找匹配项,下面的 DEMO_LK_Customer 在Lookup 组件中被称为 - Reference Table/Set 引用表/引用集,前面默认的 Full Cache 缓存的就是这里的 Reference Table - DEMO_LK_Customer。

解释一下这个关联和配置的含义 -

左边 Available Input Columns 来源于 Input 即数据源中输出的列,这些列会作为 Lookup 组件继续向下一个组件输出的列。

Available Lookup Columns 来源于 Reference table 即在缓存中的数据,已选中的 CustomerID 也会作为 Lookup 组件继续向下一个组件输出的列。

中间的黑色实心线描述了查询时的关联规则,以左边为驱动表到右边缓存表中查找 CustomerID 一致的数据,找到了则匹配成功,找不到则不匹配。

设置了如果不匹配则输出不匹配的选项,因此在 Lookup 组件之后能看到 Lookup Match Output 和 Lookup No Match Output 选项。

我们要把匹配的 CustomerID, 将 Input 作为源,将 Reference Table 作为目标表,将 CustomerID 匹配的其它列的数据更新到目标表中。

添加组件 OLE_Command 来更新 DEMO_LK_Customer 目标表,选择的是 Lookup Match Output -

UPDATE DEMO_LK_Customer SET CustomerName = ?, CustomerCompany = ?, CustomerAddress = ? WHERE CustomerID = ?

设置参数,这里就能看到有两个 CustomerID,一个是来源于 Input 的 CustomerID,一个则是上一个数据源中 OLE_SRC_LegacyCustomer 的 CustomerID,这里随便制定哪一个 CustomerID 都可以。

添加一个新组件 OLE DB Destination 连接的是 Lookup NO Match Output,并设置 DEMO_LK_Customer 为目标表,表示如果不匹配则添加新数据。

输入输出的 Mapping 关系。

执行 Package,看到从数据源中向下输出 5 条数据,其中有 3 条数据与 Reference Table 通过 CustomerID 匹配上,因此根据 CustomerID 将最新的从 Input 中输出的信息更新到已存在的目标表中。另外两条不匹配,则添加到目标表中。

注意这里提到的几个表虽然有的是同一张表,但是它们的角色是不一样的 -

  • OLE_SRC_LegacuCustomer 中的表 DEMO_LK_LegacyCustomer - 作为 Lookup 组件  LKP_Customer 中的输入源,被称为 Input Table。
  • LKP_Customer 中引用的表 DEMO_LK_Customer 在 Lookup 组件中被称为 Reference Table。
  • OLE_CMD_UpdateCustomer 和 OLE_DST_InsertNewCustomer 中出现的表 DEMO_LK_Customer 是目标表。

对于一下最后源表和目标表的数据,保持了同步,前提就是 CustomerID 在两张表中都能够唯一确定一条数据。在数据仓库的设计中,也会设计一个 Key 能够唯一确定业务系统和数据仓库中的一条数据,使它们能够在逻辑上能够关联起来。

但是这里有一个问题,就是第2条数据没有变化,但是也会执行一次 Update 操作,可以看上面的例子中,Update 操作显示的是3条数据输入了。如果数据量比较多的情况下,像这样的 Update 是没有必要的。

因此下面要对这个例子进行一个简单的改造,假设只有 CustomerCompany 和 CustomerAddress 会不一致的情况下,可以如何处理来避免无谓的更新操作。

我的改造是在查找匹配之后,添加一个组件 Conditional Split - CS_CheckValues 对输出列做一个判断,只在 CustomerCompany 和 CustomerAddress 不一致的情况下做出更新。

并且在 Lookup 组件中做出修改,因为要比较 Input table 和 Reference table 的两个列,因此选中右边的几个列。

检查的规则有3个,当两个列都不一致的时候,到某一个列不一致的时候,并且也应该按照这种顺序来确保第一种规则应该最先检查。

(_CustomerName != ContactName) && (CustomerAddress != _CustomerAddress) && (CustomerCompany != _CustomerCompany)

_CustomerCompany != CustomerCompany

CustomerAddress != _CustomerAddress

最后添加相应的组件按照不同的规则执行对应的更新语句 -

--UPDATE DEMO_LK_Customer SET CustomerName = ?, CustomerCompany = ?, CustomerAddress = ? WHERE CustomerID = ?

--UPDATE DEMO_LK_Customer SET CustomerName = ? WHERE CustomerID = ?

--UPDATE DEMO_LK_Customer SET CustomerAddress = ? WHERE CustomerID = ?

再次执行这个 Package 的时候就能看到更新的时候只有两条数据更新了,这样就避免了不必要的全部更新。

这个例子往小了说就是一个表到另外一个表根据那些列然后关联查询出一些列合并或者不合并输出,往大了说可以想象一下更多的场景。比如数据源是一个或者一批文件,Excel,需要定期将文件或者Excel中的数据同步更新到一个数据表中。比如将业务系统中的表数据更新到数据仓库中,更新一下数据仓库中的一些维度属性或者事实数据(事实数据一般很少更新),或者添加一些新的事实数据。所以,Lookup 的使用在 SSIS 中相当于大多数组件来说使用的频率还是比较高的。虽然,它的某些功能实现完全可以用其它的组件或者逻辑来代替,甚至直接使用 SQL 语句。但是某些时候,我们还是还考虑使用 Lookup,因为 Lookup 里有一些缓存的设计,可以提高我们处理数据的效率,特别是在 SSIS Package 中反复使用到同一个 Reference 对象的时候。

了解 Lookup 的缓存模式

下面提到的缓存模式只适用于 OLE DB Connection Manager,  Cache connection manager 类似于 OLE DB Connection Manager 中的 Full Cache Mode。

Full Cache 完全缓存模式

这是 Lookup 的默认选项,选择这个模式后,在数据流 Data flow 真正执行之前就会将表中的数据或者对应查询结果的数据一次性的从数据源中将数据缓存到内存中。

特点:

  • 数据流(SSIS)执行之前缓存全部结果集。
  • 消耗内存大,增加了数据流的启动时间。
  • 在数据流启动之后执行速度要快,数据不需要从数据源中再次读取。
  • 数据源中的数据更新此时将不再影响到缓存中的数据。
  • 缓存中的数据可以被后面的组件重复使用。

什么时候该使用 Full Cache?

  • Lookup 数据集比较大的时候,一次加载到内存可以反复使用,而不需要反复的去查询数据库。
  • 数据库服务器不在本地,为了减少查询次数的情况下也要考虑使用 Full Cache。

使用 Full Cache 模式时要注意的地方:

  • 数据全部缓存在内存中,如果内存不够并不会将超出部分的数据缓存到磁盘上,而是直接报错 - Run out of memory。
  • 由于数据集缓存在内存中,所以在使用 Lookup 的时候不应该直接使用表对象,而应该通过写 SELECT 语句来减少不必要的列输出并且可以加上 WHERE 条件来限定一下数据集的大小,简而言之缓存的数据应该只包含有用的数据。
  • 数据一旦缓存,那么在数据流执行过程中就不会再去检测之前源数据是否发生改变或者更新等等,除非数据流重新启动执行。

Partial Cache 部分缓存模式

部分缓存模式下,数据流开始时缓存还是空的。当时数据流开始执行后,当 Lookup 组件需要根据输入行找匹配数据的时候,这时 Lookup 组件会先检查一下缓存有没有匹配的数据,如果没有就查询数据库,如果在数据库中查到匹配的数据行的时候就把这个数据行缓存起来,以便下次使用。

查询的过程可以这样理解,比如 Input Source 中有一个 ID1 与 Lookup 对象的 ID2 匹配,那么每次就是拿 ID1 到 Lookup 的缓存中查一下有没有 ID2的值和ID1的值匹配,如果没有的话就用 ID1的值作为一个参数到 ID2 所在的数据库进行查询,因为每次查询的结构是一样的,所以只通过传参数的形式,某种程序上重用了查询语句。

特点:

  • 数据流启动之前,缓存为空,数据流启动时间要比完全缓存的情况下要快。
  • Lookup 的时候会慢,因为总要检查缓存,如果有的话就直接用,如果没有的话就需要查询数据库,每次查询都是一次开销。如果数据量比较大的话,那么开销就会非常大。
  • 可以在 Advanced Options 中设置最大缓存,一旦缓存中的实际数据大小超过这个最大值的话,就会自动清理那些较少使用的数据为新的数据腾出空间。

什么时候该使用部分缓存?

  • Lookup 缓存对象数据量较少的时候,不需要花时间等待全部缓存结束后再开始数据流的执行。

No Cache 无缓存模式

每次匹配查询都会去数据库查一次。这种缓存模式下,数据量不大并且内存比较紧张的情况下才会使用,当然它对内存的消耗也相对最小。

以上三种都是 OLE DB 的连接模式,从 SQL Server 2008 开始也支持了一种新的缓存模式 - 文件缓存模式。文件缓存是将 Reference table 中的数据存放到一个共享文件中可以供后面使用同一 Reference table 的 lookup 使用。它对内存的消耗很少,文件的数据直接存放在磁盘上,因此可以处理非常大的 Reference table 数据。

我个人觉得大多数情况下会选择 OLE DB 下的 Full Cache, 因为一般的BI项目数据量比较大并且数据大多主要是分析历史数据,所以对数据的实时性要求不高。同时,现在大多数服务器的环境也有条件让我们一次性加载足够多G的数据放到内存中缓存起来以重复使用。

更多 BI 文章请参看 BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server) 如果觉得这篇文章看了对您有帮助,请帮助推荐,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。

转载于:https://www.cnblogs.com/dream1699/p/9648431.html

微软BI 之SSIS 系列 - Lookup 组件的使用与它的几种缓存模式 - Full Cache, Partial Cache, NO Cache...相关推荐

  1. 微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug

    开篇介绍 前些天自己在整理 SSIS 2012 资料的时候发现了一个功能设计上的疑似Bug,在 Script Task 中是可以给只读列表中的变量赋值.我记得以前在 2008 的版本中为了弄明白这个配 ...

  2. 微软BI 之SSIS 系列 - 理解Data Flow Task 中的同步与异步, 阻塞,半阻塞和全阻塞以及Buffer 缓存概念...

    开篇介绍 在 SSIS Dataflow 数据流中的组件可以分为 Synchronous 同步和 Asynchronous 异步这两种类型. 同步与异步 Synchronous and Asynchr ...

  3. 微软BI 之SSIS 系列 - 利用 SSIS 模板快速开发 SSIS Package

    开篇介绍 在做 ETL 项目的时候,往往很多 Package 的开发都是基于相同的模型和流程.比如在 Package 开始运行时需要向 Process Log 表中插入记录,在 Package 运行结 ...

  4. 微软BI 之SSIS 系列 - 通过设置 CheckPoints 检查点来增强 SSIS Package 流程的重用性...

    开篇介绍 通常一个 ETL Package 是由多个控制流和数据流共同组成,有的时候 ETL 的步骤可能会比较多,整个流程执行下来的时间可能比较长.假设在 ETL Package 中包含5个Task, ...

  5. 微软BI 之SSIS 系列 - 平面文件格式的区别(Delimited,Fixed width,Ragged Right, Fixed width ...)...

    开篇介绍 SSIS 中处理文件,一般在描述输出平面文件格式的时候通常会出现以下几种选项: Delimited - 默认输出列使用逗号分隔,也可以选择其它的诸如 | ,或者 Tab 等. Fixed W ...

  6. 微软BI 之SSRS 系列 - 解决Pie Chart 中控制标签外部显示与标签重叠的问题

    微软BI 之SSRS 系列 - 解决Pie Chart 中控制标签外部显示与标签重叠的问题 参考文章: (1)微软BI 之SSRS 系列 - 解决Pie Chart 中控制标签外部显示与标签重叠的问题 ...

  7. 微软BI 之SSRS 系列 - 报表邮件订阅中 SMTP 服务器匿名访问与 Windows验证, 以及如何成功订阅报表的实例...

    这篇文章源于在上一篇博文中有园友提出订阅 SSRS 报表时的一个问题,  于是就好好总结了一下,把有关 SSRS 报表订阅的要点和容易出现问题的地方写出来,希望对大家有所帮助! 参看上一篇博文 - S ...

  8. 微软BI 之SSRS 系列 - 使用 LookupSet 和 Adjacent Group 等高级技巧在报表中跨 Dataset 分组查询...

    SSRS 报表中有一些高级的技巧,平常很少用到,下面我通过这个案例来展现一下如何在实际开发中使用它们,并且如何解决一些实际的需求. 这张报表分别统计了不同的 Product 产品在不同的月份的 Ord ...

  9. 微软BI 之SSAS 系列 - 在 SQL Server 2012 下查看 SSAS 分析服务的模型以及几个模型的简单介绍...

    在SSDT中部署一个 SSAS 项目到本地服务器上出现错误. You cannot deploy the model because the localhost deployment server i ...

最新文章

  1. Linux学习之Vi编辑器常用命令
  2. Juniper SSG 防火墙安全防护之拒绝服务×××[新任帮主]
  3. 第三个spring冲刺第5、6、7天(三天汇总)
  4. 提高网速软件_【干货】C盘空间不够用,这款软件或许会帮到你!一键清除C盘多余文件...
  5. 2021-03-09 PPT字号设置规则和图片网站(from 旁门左道)
  6. 在csdn上关于Silverlight有用文章收集
  7. [python爬虫] 招聘信息定时系统 (一).BeautifulSoup爬取信息并存储MySQL
  8. 洛谷2619/bzoj2654 Tree(凸优化+MST)
  9. 干货下载丨开源数据库安全管理
  10. jquery系列教程8-jquery插件大全
  11. 问题六十八:光照模型(Light model)——关于“环境光”模型的补充
  12. Git(6)-- 记录每次更新到仓库图文版(git clone、status、add、diff、commit、rm、mv命令详解)
  13. Spring之Bean的作用域、使用外部属性文件、mchange-commons-java-0.2.11.jar下载
  14. 计算机人工智能领域英文文献,人工智能英文参考文献精选(3)
  15. linux redis3.2.5安装及redis集群创建
  16. deepdive的股权关系抽取实践
  17. ps 如何制作动态打字图?
  18. 史上最全面的苏州工业园区虚拟住房补贴申请攻略
  19. 波段测试软件,超好用的波段副图(通达信公式 副图 源码 测试图)
  20. 从文件获取文件内容并提取promise对象的result结果

热门文章

  1. 2022-2028年中国高纯铜市场研究及前瞻分析报告
  2. 2022-2028年中国手机支付市场投资分析及前景预测报告
  3. Java开发的环境搭建
  4. 【数据结构】链表中的 指针,地址
  5. LeetCode中等题之删除链表的中间节点
  6. LeetCode简单题之两栋颜色不同且距离最远的房子
  7. 深度树匹配模型(TDM)
  8. PyTorch 图像分类
  9. 每秒能捕捉万亿帧的相机
  10. 芯片内亿万的晶体管制程工艺