2010-11-10 63 views
1

我有幾個Oracle過程生成/返回大量需要寫入文件的數據。我目前正在試圖用數據讀取器來完成。它似乎工作,我已經成功地生成了一個479mb文件沒有任何問題。從我檢索dataReader來完成文件的時間不到4分鐘。使用.Net中的Oracle DataReader產生的巨大性能問題

但是我得到一個特定過程的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問題。

+2

沒有足夠的信息來回答atm ...除了是拋出異常,這是默默處理? – 2010-11-10 04:21:05

+0

你可能應該發佈更多完整的代碼... – 2010-11-10 04:23:51

回答

3

數據庫實際在做什麼?

帶有GROUP BY或ORDER BY的查詢可能需要生成完整的結果集,然後在返回一行之前對其進行排序/聚合。掃描大表的查詢可能會在前幾個塊中找到50行,然後再讀取另外10萬個塊,然後再找到另一個塊。

我建議你忽略VB代碼併發布數據庫代碼。

+0

程序是荒謬的巨大;但它看起來像使用大量的遊標來填充Oracle臨時表。返回的Ref Cursor是一個SELECT * FROM該臨時表。 – 2010-11-10 04:49:51

+0

然後我認爲你幾乎可以保證問題出現在PL/SQL代碼和查詢中。請向您的DBA尋求一些幫助,以瞭解詳情。 – 2010-11-10 08:04:25

2

我假設你說「特定過程」時,你的意思是你正在調用具有參數REF參數的OUT參數的Oracle存儲過程。您的DataReader然後從該過程返回的遊標中獲取。是這樣嗎?

如果是這樣,您可以消除.Net代碼並編寫一個調用過程的PL/SQL塊,並從光標中提取所有數據以查看您是否在那裏獲得相同的行爲? Oracle在遊標打開時不會實現數據 - 它在客戶端獲取數據時實現結果。因此,如果Oracle必須在發現第N + 1行之前實現並過濾出一堆數據,那麼Oracle可能需要做相當多的工作才能獲取第N行。如果在數據庫上運行的PL/SQL中看到相同的行爲,那幾乎可以確定發生了什麼。如果你在PL/SQL塊中沒有看到任何問題,那麼中間層必須進行一些操作。

+0

謝謝 - 是的,它是一個OUT參數,它是REF CURSOR。我將在PL/SQL中進行嘗試並進行比較。 – 2010-11-10 04:42:27

1

只是一對夫婦的一般性意見,對你的問題的原始版本:

如果您正在使用微軟。NET Framework的內置System.Data.OracleClient提供程序類,您可能會從Oracle's own updated .NET Provider獲得更好的性能。

如果每次運行的時間都有變化,也許.NET垃圾收集器正在踢入您示例中未看到的一些內存使用情況(即,如果許多對象正在被實例化並丟棄)。