Condividi tramite


Dynamic Parameters造成的linked server性能问题

曾今遇到这样一个linked server的性能问题。

客户这边的linked server是从一台SQL Server 2000的服务器连接到一台后端的Oracle的数据库。客户遇到的问题是,他们将linked server运行在out of process模式下时,执行一句类似”select * from Oracleserver.databasename.schema.T where…”的查询来获取Oracle上的数据,但该查询花了很长时间都没运行结束。然而,再另一台SQL Server上建立linked server (运行在in process模式下)连接到同样的Oracle数据库,运行同样的语句,结果就能很快返回。

是什么原因造成了这样的性能差异呢?

客户通过跟踪Oracle的查询运行状况,发觉在有问题的Linked Server上,运行查询时会在Oracle那边对表T做一个全表扫描,然后把表T上所有的数据返回给SQL Server。然后在SQL Server那段对这些数据做过滤(也就是所有的where条件都是在SQL Server中被执行的)。不过在那套好的linked server上,所有的过滤操作是在Oracle端就执行完成的,然后Oracle端直接把过滤完的数据返回给SQL Server。在表T的数据量非常大的情况下,这两种不同的行为会造成返回到SQL Server端得数据量有巨大的差异。考虑到网络传输大数据的延迟和SQL Server需要调用大量IO来缓存接受到的数据,这种行为的差异会最终导致查询性能上的巨大区别。

客户一开始以为是out of process模式的问题,但是即使我们把有问题的linked server设置为in process模式下,问题依旧存在。

我们这里搭建了一个测试环境来模拟客户那里遇到的问题,并且查阅了相关的资料。我们发觉,当linked server使用四段式方式(Oracleserver.databasename.schema.T这样的形式)来访问后端Oracle数据库的时候,默认的行为就是把所有的数据传送给SQL Server然后在SQL Server端做过滤。也就是说,这事实上是MSDAROA(微软的Oracle驱动)的一个标准行为。

那么是什么原因使得另一套Linked Server会直接在Oracle端做过滤呢?

 

最终的研究表明这其实是受到一个叫”Dynamic Parameters”的MSDAROA设置的影响。当”Dynamic Parameters”被设置为1的时候,就会出现这种状况。

你可以到以下注册表项下面找到Dynamic Parameters的设置。

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Providers\MSDAORA]

如果你找不到Dynamic Parameters这个值或者这个值为1,则数据就是在Oracle端先过滤然后返回。反之,如果Dynamic Parameters值为0(即disabled),则会把所有数据都返回到SQL Server端。