2012-08-23 7 views
8

.NetとJavaを使用してOracle DBから1 mlnレコードを読み取ります。 .Netで私はJava ojdbc6シンクライアントでODP.Netを使用しています。 .Net読み込みデータには約10秒かかり、Javaでは約2分かかります。 なぜこのような大きな違いがありますか?.Netを使用してOracle DBからデータを読み取ることは、Javaを使用するよりも10倍高速です

ネット::ここで

はコードである

 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(); 
    } 

EDIT:setFetchSizeメソッドは、()のおかげで、仕事をしてくれました。

+3

ちょうど推測:Javaで をあなたが専門のネイティブクライアント.NETで、「どのようなレベル」とばかりJDBCドライバを使用している... しかし、一般的には、.NETは高速です;) – TheHe

+2

私は思いますあなたは間違った前提から始めます:Javaは高速になることができます。 –

答えて

8

デフォルトでは、ResultSetは完全に取得され、メモリに格納されます。これは、大きな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

@Adamはい私は確信しています。そして推測すると、それはJDBCドライバのデフォルトの動作です。 –

6

私の経験では、Oracle JDBCドライバは、大量転送のためにすぐに構成されていません。デフォルトでは、一度にネットワーク上で10レコードしか転送されません。したがって、レコードが1,000,000件の場合、ドライバには100,000件のネットワークアクセスが発生します。

あなたは、このコードを一度にフェッチするレコード数ResultSetを伝えることができます:

result.setFetchSize(1000); 

は、異なるサイズで試してみてください。私が取り組んでいる少なくとも1つのアプリケーションでは、処理時間が数分から数秒に大幅に短縮されています。

関連する問題