我们的大型应用程序(VB.Net,Framework 3.5)从一开始就或多或少地开发使用SQL Server和SQL Server。当然有一天有人把它卖给了客户,并承诺我们可以让它在Oracle(10g及以上版本)上运行,现在它确实可以,但我们有相当大的性能问题。
这源于几乎所有SQL(包含在应用程序代码中)都在表单的参数化查询中
SELECT Col1, Col2, Col3 FROM TableName WHERE IdCol = @EntityId
然后将其传递给我们的数据访问层以及参数名称数组,类型数组和值数组,然后使用Enterprise Library 5执行以处理实际连接等等。
当这个项目开始时,有人意识到Oracle需要
形式的参数:EntityId
并决定不是试图找到并重新编写SQL的每一部分(这个应用程序单独有大约一百万个LOC,套件中还有其他一些),他们会添加一个在查询执行之前调用的函数在查询和参数名称数组中用@替换@。它还删除了'WITH NOLOCK',方括号,并替换了连接字符和SQL Server使用的其他此类人工制品,但Oracle不使用。当然,问题在于字符串搜索和替换是昂贵的,并且在应用程序中的一个简单操作中,有两个以上的简单查询是按顺序执行的。对SQL Server来说,这根本不需要时间,但是对于Oracle平台,它需要花费20-30秒。
理想情况下,我想重新编写大量代码来清除糟糕/低效的代码,设计和修复狡猾的架构,并用nHibernate或Entity Framework替换。但由于商业压力和任务的规模,这种情况不会很快发生。
鉴于我不太可能被允许做出如转换ORM或重新构建大量代码这样巨大的根本性变化,我的问题很简单:
有没有办法让SQL Server或Oracle理解另一个参数标识符,或者以一般方式编写参数化查询的一些明智,简单的方法,而不需要大量的字符串替换或IF ... Else语句依赖于目标平台?我意识到我可能仍然需要编辑应用程序中的几乎所有SQL语句,但如果是这样的话那么就是这样,我只需将这个想法卖给我的老板。
干杯
答案 0 :(得分:1)
我认为最简单的方法就是优化查询转换。例如,您可以只缓存转换后的查询,一旦转换查询,然后下次需要转换它,您就可以从缓存中获取它。您可以使用查询字符串的哈希码作为缓存的密钥。像查询计划缓存。此外,您还可以自行分析和优化查询转换。
这种简单的缓存方法用于实际应用。例如NHibernate Linq(在NH3.0中)提供程序将Linq表达式转换为内部HQL语言的AST,然后将其转换为sql。并在每一步它缓存“查询计划”,所以如果需要再次转换相同的查询(相同的结构,不同的参数),nh可以从缓存中获取