簡體   English   中英

.Net中Oracle DataReader的重大性能問題

[英]Big Performance Problems With Oracle DataReader in .Net

我有一些Oracle過程可以生成/返回大量需要寫出到文件中的數據。 我目前正在嘗試使用數據讀取器。 它似乎正在運行,我已經成功生成了479mb的文件,沒有任何麻煩。 從我檢索dataReader到完成文件花了不到4分鍾的時間。

但是我為特定過程獲得的dataReader正在爬網 真是太慢了。 我修改了代碼,以嘗試更好地了解發生了什么...。

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問題。

數據庫實際上在做什么?

使用GROUP BY或ORDER BY的查詢可能需要生成完整的結果集,然后對其進行排序/匯總,然后再返回一行。 掃描大型表的查詢可能在前幾個塊中找到50行,然后在找到另一個塊之前先讀取十萬個塊。

我建議您忽略VB代碼並發布數據庫代碼。

我假設當您說“特定過程”時,是指您正在調用一個具有OUT參數(即REF CURSOR)的Oracle存儲過程。 然后,您的DataReader從該過程返回的游標中獲取。 是這樣嗎

如果是這樣,您是否可以消除.Net代碼並編寫一個PL / SQL塊來調用該過程並從游標中獲取所有數據以查看是否在該處獲得了相同的行為? 打開游標時,Oracle不會具體化數據,而是在客戶端獲取數據時具體化結果。 因此,如果甲骨文必須在找到第N + 1行之前實現並過濾掉一堆數據,它可能需要做大量工作來獲取第N行。 如果在數據庫上運行的PL / SQL中看到相同的行為,那幾乎肯定是發生了什么。 如果您在PL / SQL塊中看不到任何問題,那么中間層一定正在發生某些事情。

對於您問題的原始版本,僅作幾條一般性評論:

如果您使用Microsoft .NET Framework的內置System.Data.OracleClient提供程序類,則可能會從Oracle自己更新的.NET Provider獲得更好的性能。

如果時間隨每次運行而變化,則可能是.NET垃圾收集器開始處理您的示例中未看到的某些內存使用情況(即,如果實例化並丟棄了許多對象)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM