2015-02-10 124 views
2

我有一个Oracle绑定查询,当它在我的C#程序中执行时非常慢(大约2分钟),但在SQL Developer中运行得非常快。它有两个参数打表的索引:Oracle Bind查询速度很慢

select t.Field1, t.Field2 
from theTable t 
where t.key1=:key1 
    and t.key2=:key2 

另外,如果我删除了绑定变量,创建动态SQL,它运行就像它在SQL Developer中。

有什么建议吗?

顺便说一下,我正在使用ODP。

+1

我不知道是否这是在不同的优化器设置(如first_rows vs all_rows)在c#vs sql开发人员。有关更多信息,请参阅[Tom Kyte撰写的此文章](http://www.oracle.com/technetwork/issue-archive/2008/08-may/o38asktom-085659.html)。也许你可以检查v $ sql和v $ sql_shared_cursor来查看你是否有多行用于同一个sql语句,如果是这样,是否有不同的优化器模式是问题? – Boneist 2015-02-10 16:44:45

回答

1

参数绑定到C#中正确的数据类型?列key1key2数字,但参数:key1:key2是字符串?如果是这样,查询可能会返回正确的结果,但需要隐式转换。这种隐式转换就像使用一个函数to_char(key1),这可以防止使用索引。

+0

字段key1和key2分别是CHAR(8)和CHAR(2)。参数也是CHAR(8)和CHAR(2)。 – wcm 2015-02-11 20:02:28

1

还请检查查询返回的行数是多少。如果这个数字很大,那么C#可能会获取所有行,而另一个工具只能是第一个口袋。在这种情况下,获取所有行可能需要更多的磁盘读取,这比较慢。要检查这个尝试在SQL Developer中运行:

SELECT COUNT(*) FROM (
    select t.Field1, t.Field2 
     from theTable t 
    where t.key1=:key1 
     and t.key2=:key2 
) 

上面的查询应该获取数据库块的最大数量。

这种情况下的好工具是tkprof实用程序,它显示了SQL执行计划,在上述情况下可能会有所不同(但它不应该是这样)。

也可能是您意外连接到不同的数据库。在这种情况下,比较查询结果是很好的。

由于您提出“绑定速度慢”,我假设您已经检查了SQL,没有绑定,速度很快。在99%的使用绑定使事情变得更好。请检查具有常量的查询是否会运行得很快。如果是,则问题可能是key1或key2列的隐式转换(例如,t.key1是一个数字,并且:key1是一个字符串)。

+0

记录数很少。在10和100之间。 – wcm 2015-02-11 20:05:46

1

如果您在sql developer中用静态变量替换绑定变量,那么您并不真正运行相同的测试。确保你使用绑定变量,并且如果速度太慢,你只是由于一个糟糕的缓存执行计划而陷入困境。更新该表上的统计数据应该解决它。

但是,如果您实际上在SQL开发人员中使用绑定变量,请继续阅读。 TLDR版本是ODP.net运行的参数有时会导致稍微更悲观的方法。从更新统计开始,但让你的dba在两种情况下捕捉执行计划并进行比较以确认。

我从这里重新发布我的回答:https://stackoverflow.com/a/14712992/852208 我认为你标记为重复的,但你的标题是有点更简洁,因为它识别查询并在SQL Developer中跑得快。我会以另一种方式欢迎处理意见。

将以下内容添加到您的配置将发送odp。网络追踪信息记录到日志文件:

这可能只会是有益的,如果你能及时发现有很大的差距。实际上,行正在进入,只是速度较慢。

尝试在连接字符串中添加“enlist = false”。我不认为这是一个解决方案,因为它会有效地禁用分布式事务,但它应该可以帮助您隔离问题。您可以从Oracle forumns后得到一点点信息:

从ODP角度来看,所有我们真的可以指出的是,当OCI_ATR_EXTERNAL_NAME和OCI_ATR_INTERNAL_NAME 是底层的OCI连接上设置发生 行为(当 distrib tx support启用时会发生什么情况)。

我猜你没有看到的是,该执行计划实际上是不同的odp.net调用和SQL Developer的通话之间(指实际的性能损失实际上是存在的服务器上)。让dba跟踪连接,并从odp.net调用和直接从SQL Developer调用(或使用enlist = false参数)获取执行计划。

如果您确认不同的执行计划或者您想在黑暗中抢先拍摄,请更新相关表格的统计数据。在我的情况下,这纠正了这个问题,表明执行计划生成并不真正遵循不同类型连接的不同规则,但是在涉及分布式事务时,成本分析只是略微更加轻松。查询提示以强制执行计划也是一种选择,但仅作为最后的手段。

最后,它可能是一个网络问题。如果您的odp.net安装使用新的oracle主目录(除非您进行了一些安装后配置,否则我会期待),那么tnsnames.ora可能会有所不同。 tnsnams中的主机名可能不完全合格,从而导致解决服务器更多延迟。我只希望在这种情况下第一次尝试(而不是后续的尝试)速度缓慢,所以我不认为这是问题,但我认为应该提及。

+0

我从应用程序中复制sql并保持绑定变量不变。 – wcm 2015-02-11 20:05:01