2012-08-23 61 views
8

我正在使用.Net和Java從Oracle數據庫讀取1百萬條記錄。 在.NET中,我使用ODP.Net,在Java ojdbc6瘦客戶端中。 .Net讀取數據大約需要10秒鐘,而在Java中需要將近2分鐘。 爲什麼有這麼大的差異?使用.Net從Oracle數據庫讀取數據比使用Java快10倍

下面是一個代碼:

的.Net:

 try 
     { 
      DateTime dt1 = DateTime.Now; 

      OracleConnection con = new OracleConnection(); 
      con.ConnectionString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myHost)(PORT=myPort)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=myService)));User Id=myId;Password=myPass;"; 

      con.Open(); 
      string cmdQuery = "SELECT * FROM DROPME"; 

      OracleCommand cmd = new OracleCommand(cmdQuery); 
      cmd.Connection = con; 
      cmd.CommandType = CommandType.Text; 

      int i = 0; 
      OracleDataReader reader = cmd.ExecuteReader(); 
      while (reader.Read()) 
      { 
       Object o1 = reader.GetValue(0); 
       Object o2 = reader.GetValue(1); 
       Object o3 = reader.GetValue(2); 
       Object o4 = reader.GetValue(3); 
       Object o5 = reader.GetValue(4); 
       Object o6 = reader.GetValue(5); 
       Object o7 = reader.GetValue(6);      
       i++; 
      } 

      DateTime dt2 = DateTime.Now; 

      double elapsed = (dt2 - dt1).TotalSeconds; 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 

的Java:

try 
    { 
     long t0 = System.currentTimeMillis(); 
     oracleDataSource = new OracleDataSource(); 
     oracleDataSource.setURL("jdbc:oracle:thin:myId/[email protected]:myPort:myService"); 
     Connection connection = oracleDataSource.getConnection(); 
     PreparedStatement statement = connection.prepareStatement("SELECT * FROM DROPME"); 
     ResultSet result = statement.executeQuery(); 
     int i = 0; 
     while (result.next()) 
     { 
      result.getObject(1); 
      result.getObject(2); 
      result.getObject(3); 
      result.getObject(4); 
      result.getObject(5); 
      result.getObject(6); 
      result.getObject(7); 
      i++; 
     } 
     long t1 = System.currentTimeMillis(); 
     long elapsed = (t1 - t0)/1000; 
     int t = 0; 
    } 
    catch (Exception ex) 
    { 
     ex.printStackTrace(); 
    } 

編輯:的setFetchSize()做的工作,謝謝。

+3

只是猜測: 在Java中你只使用JDBC驅動程序與「任何級別」,在.net中一個專門的本地客戶端... 但是,在一般情況下,.NET更快;) – TheHe

+2

我認爲你從一個有缺陷的前提開始:Java可以很快。 –

回答

8

默認情況下,Java會將ResultSets完全檢索並存儲在內存中。這對於具有大型ResultSet的查詢來說並不好。要使用流結果或數據U必須使用:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); 
stmt.setFetchSize(Integer.MIN_VALUE); 

我沒有比較過所花費的時間,但我想這會快很多。

+0

你確定ResultSet被完全檢索並存儲在內存中嗎?這是JDBC標準的一部分還是您在某些JDBC驅動程序中觀察到的行爲? –

+0

我也會試試這個,但不要打賭它......或者你可以測試在.Net中加載數據到一個數據集,循環它,看看它是否也需要2分鐘。有趣的知道... – Asken

+0

@亞當是的,我敢肯定。正如你猜測的那樣,這是JDBC驅動程序的默認行爲。 –

6

根據我的經驗,Oracle JDBC驅動程序對於大容量傳輸而言是開箱即用的。默認情況下,它一次只能在網絡上傳輸10條記錄。因此,如果您有1,000,000條記錄,則該驅動程序將招致100,000次網絡訪問。

你可以告訴ResultSet多少記錄在同一時間使用此代碼獲取:

result.setFetchSize(1000); 

隨意用不同大小的實驗。它在至少一個我曾經工作過的應用程序中大大減少了處理時間(從幾分鐘到幾秒)。