【问题标题】:Oracle query is slow (or fails) from .NET app but is fast from SQL Developer.NET 应用程序中的 Oracle 查询很慢(或失败),但 SQL Developer 中的查询速度很快
【发布时间】:2010-10-30 05:02:14
【问题描述】:

我们使用 ODP.NET 对 Oracle 数据库执行查询,通常它工作正常。但是,在该数据库中有一个特定的数据库和一个特定的视图,我们只是无法从 .NET 完成查询。例如:

SELECT some_varchar_field FROM the_view WHERE ROWNUM < 5;

如果我在 Oracle SQL 开发人员中执行此查询,它会在不到一秒的时间内完成。如果我使用 ODP.NET 从我们的 .NET 应用程序执行相同的查询,它会挂起并最终产生“ORA-03135:连接丢失联系”错误。我认为将其限制为仅几行可以消除它作为 FetchSize 问题的可能性。

还有其他查询我可以成功执行,但是我们的程序比 SQL Developer 慢。同样,我意识到 SQL Developer 最初只获取前 50 行的数据,但我认为 ROWNUM 条件将其排除在外。

Oracle SQL Developer 使用的连接或命令与我们的应用程序使用的连接或命令有什么不同会导致速度差异?

很遗憾,我没有访问服务器的权限(只能对其运行 Oracle 查询)。

谢谢。

更新:我已尝试使用 Microsoft 的 Oracle 提供程序进行相同的查询,它执行得非常快。不幸的是,该提供程序已被弃用,因此这不是一个长期的解决方案。

【问题讨论】:

    标签: .net oracle odp.net


    【解决方案1】:

    它与 ODP.NET 提供程序无关。问题是我们用来为我们创建连接的库(当然,Oracle SQL Developer 不使用它,我在尝试 Microsoft 提供程序时也没有使用它)在执行任何操作之前总是执行以下语句:

    ALTER SESSION SET NLS_COMP = LINGUISTIC
    ALTER SESSION SET NLS_SORT = BINARY_CI
    

    这些使 Oracle 不区分大小写。但是,它们也使所有常规索引变得无用。因为我们是从视图中查询的,所以它内置了排序。而且因为我们不拥有数据库,所以我们无法使索引语言化来解决性能问题。

    提供一种在这种(罕见的)场景中不执行这些语句的方法解决了这个问题。

    【讨论】:

    • 在这个非常有用的答案的附录中,我发现运行 ALTER SESSION SET NLS_COMP=BINARY;更改会话集 NLS_SORT=BINARY;将会话设置回其默认设置。当然,它会打开区分大小写,但这并不像慢查询那么糟糕。
    • 您是如何发现您正在使用的库正在执行这些语句的?我有一个类似的场景:立即在 Oracle Sql Developer 中,但距离应用程序只有几秒钟。在 Sql Server 上测试完全相同的场景确实更快。也许我错过了一些重要的配置。
    【解决方案2】:

    直接的想法是

    1. CLOB、BLOB 或 LONG/LONG RAW,仅几行就需要大量带宽。
    2. 无效数据(例如,有一些方法可以在日期字段中获取无效日期,这可能会使某些客户感到困惑)
    3. “the_table”实际上不是一个表,而是一个视图或具有复杂派生或具有 VPD/RLS/FGAC 安全策略的东西。
    4. 外来数据类型(空间或用户定义)。

    建议

    1. 明确列出列(例如,SELECT a,b,c FROM the_table WHERE ROWNUM
    2. 检查 v$session 中的会话以查看等待事件是什么。数据库服务器正在为此 SQL 消耗 CPU,或者它正在等待某些东西(可能是客户端)。
    3. 检查 v$sql 中的 SQL。是否有一个或多个子游标。是否有一个或多个 PLAN_HASH_VALUE。不同的子游标可以使用不同的计划。如果没有除 ROWNUM 之外的 WHERE 子句,这几乎是不可能的。

    【讨论】:

    • 可能还值得检查服务器警报日志以查看此查询是否有 ORA-600 与 ORA-03135 一起使用?
    • 我已根据您的回答更新了问题。此外,只有简单的字段(最大的字段是 varchar2(576)),即使我只选择一个字段也会出现问题。你说得对,它实际上是一个视图。
    【解决方案3】:

    视图增加了不同程度的复杂性。 “SELECT column FROM table WHERE rownum

    对于视图,您应该首先获取视图文本SELECT TEXT FROM ALL_VIEWS WHERE VIEW_NAME = ...

    ODP.NET 和 SQL Developer 会话之间有很多不同之处。我会考虑 NLS 参数(例如日期格式)和字符集设置。

    如果您可以在 v$sql 中找到 SQL,则可以执行 DBMS_XPLAN.DISPLAY_CURSOR(sql_id) 来查看不同的计划,看看您是否可以识别问题。

    【讨论】:

      【解决方案4】:

      在我在前任雇主处工作的一个项目中,我们使用 odp.net 与一个大型零售系统数据库通信,但我们会遇到连接丢失错误。

      花了很多精力来证明,但它最终成为 Oracle 数据库中的一个损坏的索引,它只被我们的查询命中。当我们的查询被执行时,DBA 最终将其追踪到在 Sun 机器上运行的进程的核心转储。我们没有使用任何类型的查询提示等,但是当我们在 Toad 中运行相同的查询时,它并没有命中这个特定的索引。奇怪??

      【讨论】:

        猜你喜欢
        • 2021-12-13
        • 1970-01-01
        • 2022-11-18
        • 2011-11-30
        • 2018-11-16
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多