Big Performance Problems With Oracle DataReader in .Net

那年仲夏 提交于 2019-12-02 11:39:05

问题


I have a few Oracle procedures that generate/return a large amount of data that I need to write out to a file. I'm currently trying to accomplish with a data-reader. It seems to be working, I've successfully generated a 479mb file without any trouble. It took less than 4 minutes from the time I retrieved the dataReader to complete the file.

But the dataReader I get for a particular procedure is crawling. It's unbelievably slow. I modified my code to try and get a better idea of what is going on....

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)

The interesting this is that my output ends up looking like this:

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

I'm really at a loss for what to do next. I can't see anything unique or different about the row that takes 07:33.5037500. Any suggestions?

EDIT:

Thanks for the responses everyone. First, as best as I can tell, no exceptions are being thrown. As suggested, I've taken a look at this particular procedure that is exhibiting the behavior above and while procedure is ridiculously massive; but it looks like it uses a lot of cursors to populate an oracle temp table. The Ref Cursor that is returned is a SELECT * FROM that temp table.

I'm writing a PL/SQL block that will open that cursor to see if the performance issue exists when I remove the .Net code....hopefully that will help; but if you've got any additional thoughts, it will be much appreciated.

Thanks once more. This does appear to be a PL/SQL issue and not a .NET problem.


回答1:


What is the database actually doing ?

A query with a GROUP BY or and ORDER BY may need to generate the full result set, then sort/aggregate it before returning a row. A query scanning a large table may find 50 rows in the first couple of blocks, then read another hundred thousand blocks before it finds another one.

I suggest you ignore the VB code and post the database code.




回答2:


I'm assuming when you say "particular procedure" that you mean that you are calling an Oracle stored procedure that has an OUT parameter that is a REF CURSOR. Your DataReader is then fetching from the cursor returned by the procedure. Is that the case?

If so, can you eliminate the .Net code and write a PL/SQL block that calls the procedure and fetches all the data from the cursor to see if you get the same behavior there? Oracle doesn't materialize data when the cursor is opened-- it materializes the results as the client fetches the data. So it is possible that Oracle has to do quite a bit of work to fetch the Nth row if it has to materialize and filter out a bunch of data before it finds the N+1th row. If you see the same behavior in PL/SQL running on the database, that is almost certainly what's going on. If you don't see any issues in the PL/SQL block, then something must be going on in the middle tier.




回答3:


Just a couple of general comments, for the original version of your question:

If you're using the Microsoft .NET Framework's builtin System.Data.OracleClient provider classes, you might get better performance from Oracle's own updated .NET Provider.

If the time shifts around each run, maybe the .NET garbage collector is kicking in on some of the memory usage that's not seen in your example (i.e. if many objects are being instantiated and thrown away).



来源:https://stackoverflow.com/questions/4141175/big-performance-problems-with-oracle-datareader-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!