微软BI 之SSIS 系列 - 在 Lookup 中使用 Cache Transform 缓存转换的运行时缓存与文件缓存

浏览: 3824

开篇介绍 

在之前的文章中我介绍到了 Lookup 查找转换控件中在 OLE DB 模式下 Lookup 的几种缓存模式: Full Cache 完全缓存,Partial Cache 部分缓存,No Cache 无缓存。这几种缓存模式可以满足我们的绝大部分需要,但是自 SQL Server 2008 R2 开始,SSIS 对 Lookup 的缓存模式做了加强,出现了另外的一种缓存模式 Cache Connection Manager 缓存连接管理器。它不仅支持数据流中的内存缓存共享,而且还支持文件缓存共享。通过内存缓存,缓存可以供多个数据流中的 Lookup 使用;通过文件缓存,缓存文件不仅可以供多个数据流使用,而且还可以供不同包中的 Lookup 控件来使用。

Cache Transform 缓存转换介绍

Cache Transform 缓存转换控件是从 2008 就开始有了的,它可以通过配置将数据缓存起来再到 Lookup 查找转换控件中使用。使用这种缓存在效率上会比从数据库中加载数据再缓存对比的过程要更高一些,因为这种缓存是可以反复使用的。另外的一种情况就是,这种缓存还可以持久化写入到本地的文件中,那么就可以在多个包中以及不同 Lookup 中来重复使用缓存文件。特别是多个 Lookup 任务,或者多个包都有相同的 Lookup 引用集需求的时候,使用文件缓存可以避免反复的查询数据库。并且还有一定非常重要,就是在 OLE DB 模式下的 Full Cache 完全缓存对内存是有要求的,即缓存的内容不能超过内存的容量,但是这里的文件缓存则是写入到磁盘上,可以最大程度上避免这种问题。

示例如下:

在数据库中有一张有关订单的 Mapping 表,我们要 Lookup 的就是这张表的内容,首先需要将它查询并缓存到缓存内存或者缓存文件中去。

这张表先通过 OLE_SRC_ORDERS 查询出来,将查询的结果交给缓存转换 Cache Transform - CT_ORDERS。

编辑 CT_ORDERS 第一次是需要创建一个缓存连接管理器的。

在缓存连接管理器中,有两种关于缓存的存放方式,默认情况下存放在内存中,这里选用文件缓存,那么不同包都可以使用同一个缓存文件。

由于在后面的 Lookup 中需要比较的列有两列 SalesOrderNumber 和 SalesOrderLineNumber,因此这里的索引依次按 1,2 序号递增;非 Lookup 列,但是需要匹配输出的列给索引序号 0。

回到 Cache 转换控件,可以看到来自于 OLE DB Source 中的三个输入列是如何和缓存配置中的列匹配的。

注意:如果要使用缓存,那么缓存必须存在于所有引用缓存的 Lookup 控件所在的数据流任务之前,或缓存所在的包必须存在于所有引用缓存的 Lookup 控件所在的包之前。

第一个含有 Lookup 数据流的任务中,输入数据源来自一个文件,包含有 SalesOrderNumber 和 SalesOrderLineNumber 以及 SalesAmount 等所有订单信息。它需要在缓存中查找对应的 SalesOrderNumber 和 SalesLineNumber 是否存在,如果存在则将对应的文件中的数据输出到一个表中。

这里只有匹配输出,不匹配的不用处理(并非真正不用处理,而是重定向的数据没有输出目标来接收)。

Lookup 控件 LKP_ORDER_LINES 中的配置,在这里如果选择了 Partial Cache 或者 No Cache 那么就只能是 OLE DB Connection Manager,即如果选择 Cache Connection Manager 是没有 Partial Cache 和 No Cache 这种概念和配置的。不匹配时数据流重定向到不匹配输出 Output,尽管后面没有处理,这也是可以的。

此时的 Connection 连接就不是之前 OLE DB Connection 中的引用数据集,通过视图,表或者查询语句来配置的了,这里就是缓存。

在查找列种,右侧的两个放大镜就是之前在配置缓存的时候一样的效果,文件数据源根据缓存中的 SalesOrderNumber,SalesOrderLineNumber 来匹配查找 SEQ_ID,如果找到就是匹配输出,输出列包括左侧文件源中的 Available Input Columns 所有列和 Available Lookup Columns 中被选中的列 SEQ_ID;如果没有找到,就是不匹配输出,输出列就只有左侧的 Available Input Columns 中的所有列。

在我的测试案例中,DFT_LOAD_ORDERS_1 和 DFT_LOAD_ORDERS_2 以及 EPT_LOOKUP_CACHE_3 中的 Lookup 除了输出的表不一样以外,其它配置都完全一致。

利用文件缓存,在一个包中的几个数据流 ( DFT_LOAD_ORDERS_1, DFT_LOAD_ORDERS_2 ) 中的 Lookup 都可以使用到,并且在其它的包 ( EPT_LOOKUP_CACHE_3 ) 也一样可以使用的到。

打开缓存连接管理器,将使用文件缓存的勾去掉,并且删除掉文件缓存的文件。

这时数据是在缓存当前包运行时的内存中的,在这个包中的位于缓存转换执行之后的所有数据流中的 Lookup 查找转换都可以访问的到,但是不同的包就无法访问了。

跟这篇文章相关的文章还有

推荐 0
本文由 BIWORK 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

1 个评论

这种缓存再用LOOKUP查找来引用查找表里的另外的列的方式,和直接在数据库里写LEFTJOIN的方式,哪个比较推荐使用?是不是从源数据库里抽取事实表的数据,尽量少关联当中的维度表数据,把维度表数据抽取到SSIS里作查找表,再让事实表流进来和查找表匹配,等于说在SSIS完成匹配而不是在有关系数据库里,不知道实际使用应该怎样处理,看书上说,能在关系数据库里JOIN匹配的话,就在关系数据库里完成,数据库是以集的方式来处理,比较高效之类的,不知道实际是如何操作好?

要回复文章请先登录注册