1

我有一些 Oracle 程序可以生成/返回需要写入文件的大量数据。我目前正在尝试使用数据阅读器来完成。它似乎正在工作,我已经成功生成了一个 479mb 的文件,没有任何问题。从我检索 dataReader 到完成文件的时间不到 4 分钟。

但是我为特定过程获得的 dataReader 是crawling。它慢得令人难以置信。我修改了我的代码以尝试更好地了解正在发生的事情......

System.Diagnostics.Debug.Write("Performing .Read() on DataReader: ")
Dim d1 As DateTime = DateTime.Now
Dim result As Boolean = myDataReader.Read()
Dim ts As TimeSpan = DateTime.Now.Subtract(d1)
System.Diagnostics.Debug.WriteLine(ts.ToString)

有趣的是,我的输出最终看起来像这样:

Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:07:33.5037500

我真的不知道下一步该做什么。我看不出占用 07:33.5037500 的行有任何独特或不同之处。有什么建议么?

编辑:

感谢大家的回复。首先,据我所知,没有抛出异常。正如建议的那样,我已经查看了这个表现出上述行为的特定程序,虽然程序非常庞大;但看起来它使用了很多游标来填充 oracle 临时表。返回的 Ref Cursor 是一个 SELECT * FROM 该临时表。

我正在编写一个 PL/SQL 块,该块将打开该游标,以查看当我删除 .Net 代码时是否存在性能问题……希望这会有所帮助;但如果您有任何其他想法,将不胜感激。

再次感谢。这似乎是 PL/SQL 问题,而不是 .NET 问题。

4

3 回答 3

3

数据库实际上在做什么?

带有 GROUP BY 或 ORDER BY 的查询可能需要生成完整的结果集,然后在返回行之前对其进行排序/聚合。扫描大表的查询可能会在前几个块中找到 50 行,然后再读取另外十万个块,然后再找到另一个块。

我建议你忽略VB代码并发布数据库代码。

于 2010-11-10T04:37:58.973 回答
2

我假设当您说“特定过程”时,您的意思是您正在调用具有 OUT 参数的 Oracle 存储过程,该参数是 REF CURSOR。然后,您的 DataReader 将从过程返回的游标中获取。是这样吗?

如果是这样,您是否可以消除 .Net 代码并编写一个 PL/SQL 块来调用该过程并从游标中获取所有数据以查看您是否在那里获得相同的行为?Oracle 不会在打开游标时实现数据——它会在客户端获取数据时实现结果。因此,如果 Oracle 必须在找到第 N+1 行之前实现并过滤掉一堆数据,那么它可能需要做很多工作来获取第 N 行。如果您在数据库上运行的 PL/SQL 中看到相同的行为,那几乎可以肯定是正在发生的事情。如果您在 PL/SQL 块中看不到任何问题,那么中间层肯定有问题。

于 2010-11-10T04:37:08.433 回答
1

对于您问题的原始版本,仅提供一些一般性评论:

如果您使用 Microsoft .NET Framework 的内置System.Data.OracleClient提供程序类,您可能会从Oracle 自己更新的 .NET Provider获得更好的性能。

如果每次运行的时间发生变化,那么 .NET 垃圾收集器可能正在处理您的示例中没有看到的一些内存使用情况(即,如果许多对象被实例化并被丢弃)。

于 2010-11-10T04:53:51.703 回答