【问题标题】:Oracle Data Access for .NET.NET 的 Oracle 数据访问
【发布时间】:2013-10-16 22:49:19
【问题描述】:

我有一个 MVC3 ASP.NET Web 应用程序,它使用 Oracle Data Provider for .NET (ODP.NET) x86 连接到 Oracle 数据库。我的应用程序中的以下代码将在 Oracle 数据库表中执行查询,然后使用 StreamWriter 将查询结果写入输出文件。

下面的代码每分钟从 Oracle 数据库表中读取大约 12,000 条记录(即使不使用流写入器写入输出文件)。

我想知道你们中是否有人知道提高性能以每分钟读取更多记录的方法 - 也许是您知道的另一个驱动程序?谢谢,非常感谢!

        _dbCommand.CommandText = query;

        using (var sw = new StreamWriter(output, append, Encoding.UTF8))
        {
            using (var reader = _dbCommand.ExecuteReader())
            {
                if (reader != null)
                {
                    var count = reader.FieldCount;

                    while (reader.Read())
                    {
                        //get records
                        for (var i = 0; i < count; i++)
                        {
                            var txt = reader[i].ToString();

                            sw.Write(txt);
                        }
                        sw.WriteLine();

                    }
                }
            }

更新:

看起来瓶颈在于 ODP.NET。从我的 Oracle 数据库中的任何表中读取/迭代“选择前 10k”类型查询需要 53 秒。

_dbCommand.CommandText = query;
using (var reader = _dbCommand.ExecuteReader())
            {
                if (reader != null)
                {
                    while (reader.Read())
                    {

                    }
                }
            }

【问题讨论】:

  • 字段分隔符在哪里???。一个快速的胜利可能是让 sql 返回一列,例如 select A + '|' + B + '|' C 作为 MyTable 中的行,除非留置权长度很大。
  • 但首先你应该看看瓶颈在哪里,数据库、网络或磁盘。
  • 这也可能有用。让数据库做它的东西,然后移动文件。 stackoverflow.com/questions/9021810/…
  • 感谢您的所有帮助,托尼​​!瓶颈在于 ODP.NET。从我的 Oracle DB 中的任何表中读取 10k 条记录需要 53 秒。在 oracle 本身中执行查询需要纳秒,所以我试图弄清楚为什么 ODP.NET 会减慢读取过程。有任何想法吗?你知道另一个更快的将 .NET 应用程序连接到 Oracle DB 的数据访问库吗?
  • 现在你把问题隔离了,我想说你最好的选择是 DBA.StackExchange 中的一个特定问题。

标签: c# oracle


【解决方案1】:

如果你想要最好的性能,那么我建议你完全跳过c#部分。

  1. 对查询运行解释计划以调整其性能。
  2. 使用 Oracle UTL_FILE 将数据写入文件。

更新

首先,您仍然需要调整您的 SQL 查询以使您的查询尽可能快地运行。

然后,问题是如何快速将数据保存到文件中。您的sw.Write 不会是最快的,因为它太频繁地写入太少的数据。

尝试将其AutoFlush 属性设置为false 并手动调用Flush 以写入磁盘。

您需要测试不同的缓冲区大小,以确定哪种效果最好。

【讨论】:

  • 感谢您的帮助!不幸的是,我们似乎无法跳过 c# 部分,因为我们需要我们的网络应用程序能够过滤 csv 并了解有关 csv 位置的某些信息,以便处理应用程序的其他区域。您是否知道在仍然使用 c# 部分的同时提高性能的方法?
  • 谢谢,雷!我尝试使用 Flush 手动写入磁盘,这似乎有所帮助,但是我发现 ODP.NET 存在瓶颈。从 Oracle DB 表中执行超过 10k 条记录的纯读取(无需写入或其他任何操作)需要 53 秒。对其他库或其他任何东西有什么想法吗?
  • 我尝试过的所有库都是 Micrsoft Oracle Client、Oracle ODP.NET 和 Devart,但我不知道哪个更快。但是,如果您没有确定瓶颈在哪里,我不会期望不同的库会提供更好的性能。同样,SQL 调优、网络延迟、数据库硬件和库都会对性能产生影响,但首先,您需要确定哪里最慢。
  • 好吧,我找到了罪魁祸首。 The issue is that ODP.NET is really slow reading from this table when a specific column that is varchar2(4000 BYTE) is included in the select statement.选择此表中除此之外的每一列仅需 4 秒。知道如何使用 ODP.NET 以不同方式处理此列吗?
  • 列需要那么大吗?如果没有,您可能需要重新调整列的大小并使其更小。您需要该列中的所有数据吗?如果没有,您可以substr 来获取前 x 个字符。如果两个问题都是肯定的,我会用多个表重新建模该列中的数据。底线是,如果您必须移动 1 吨货物,您将需要 x 量的力。在许多情况下,您会发现您不需要一次移动所有这些。事半功倍会让你获得最佳表现。
猜你喜欢
  • 2012-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 1970-01-01
  • 2016-12-05
相关资源
最近更新 更多