[翻译 from SSIS team blog]SQL2005(SSIS)的脚本及其程序集缓存

注意:由于SQL SERVER08使用的是VSTA,而05用的是VSA,所以SQL SERVER08没有下列这些问题。

脚本程序集

 VSA脚本必须在包运行前被编译。Script task组件包含在保存包的时候预编译脚本到binary code的选项。当脚本被预编译的时候,在包运行时就可以不加载语言编译器,这样会大大提高运行速度。不管怎样,预编译成为binary files会暂用一定的磁盘空间。如果你不选在预编译选项,脚本将在运行时编译,这样的结果是磁盘占用空间较少但是运行速度会下降。如果磁盘空间充裕,最好的选择是进行预编译。还有,只有预编译的脚本可以在64位环境下运行。

不管是否预编译,脚本都会被编译成为.NET assembly。加载程序的时候,会消耗内存,并且需要一个独立的应用程序域。 

2005 RTM

在2005发布的时候,SSIS没有缓存这些脚本程序集。这意味着,在一个循环里面执行循环脚本的时候,每一次循环都会建立一个新的应用程序域,而脚本程序集则会被重新加载。 这严重影响性能,并且我们在这些进程接受前不能重新加载或是销毁应用程序域,这可能导致内存方面的问题。

2005 SP1

SP1的脚本程序集缓存致力于性能的提升与内存问题的避免。在功能上保证脚本只会被加载一次,并且在以后的操作中会被重复使用。但是,每一个脚本都关联着一个独一无二的GUID... 如果你拷贝或粘贴.DTSX文件,script task或是scritp component会保留相同的GUID(尽管你修改它的代码)。那么问题就出现了-如果脚本code完全不同,但是component本身来自同一scrit task的拷贝,那么他们其中一个的scirpt将会被不会运行。

2005 SP2

通过在每次操作script code时改变GUID,SP1的问题在SP2中得到了解决。这意味着如果script code如果一样,scirpt component的名字或是component本身一样。这种情况下,对于两个这样的components,任然只有一个会运行。

 

2005 SP3

SP2中的问题是:如果同样的script components同步被执行(多线程的包同时执行两个一样的子包),他们可能共享一个dts runtime对象(一个包含变量,连接管理的对象),如果第一个实例设置变量FOO为A,第二个对象却设置为B,那么第一个对象在使用的时候对象的值将会是B。

Unfortunately this problem isn’t easily fixed without entirely disabling script caching. Because we don’t want to go back to the RTM behavior (no caching at all), we introduced a new property to the Script Task / Component to control caching - OptimizeScriptExecution. If you’re running a child package with scripts multiple times in parallel, be sure to set this value to False, which disables the cache and prevents the scripts from sharing a runtime object.

不幸的是除了关闭script caching外没有更好的方法来解决这个问题。毕竟整个RTM版本的操作不能完全修改,对此需要使用一个属性-OptimizeScriptExecution。如果需要多线程同步运行脚本,请把这个选项设置为false,来关闭cache从而阻止脚本共享一个runtime object.

 

 

 

 

 

 

posted @ 2009-06-22 17:41  refeiner  阅读(315)  评论(0编辑  收藏  举报