2012-08-23 10 views
8

Estoy leyendo 1 millón de registros de Oracle DB usando .Net y Java. En .Net estoy usando ODP.Net, en Java ojdbc6 thin client. En .Los datos de lectura tardan unos 10 segundos, y en Java tardan casi 2 minutos. ¿Por qué hay tanta diferencia?Leer los datos de Oracle DB usando .Net es 10 veces más rápido que usar Java

Aquí es un código:

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

EDIT: setFetchSize() hizo el trabajo, gracias.

+3

sólo una suposición: en Java que está utilizando sólo un JDBC-conductor con "cualquier nivel", en .net un cliente nativo especializado ... pero, en general, .net es más rápido;) Creo que – TheHe

+2

estás comenzando con una premisa defectuosa: que Java puede ser rápido. –

Respuesta

8

En Java de forma predeterminada, los ResultSets se recuperan por completo y se almacenan en la memoria. Esto no es bueno para consultas con ResultSets grandes. Para usar un resultado streaming u debe utilizar:

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

yo no he comparado el tiempo necesario, pero yo supongo que esto será mucho más rápido.

+0

¿Está seguro de que los ResultSets se recuperan por completo y se almacenan en la memoria? ¿Es esto parte del estándar JDBC o es este comportamiento que ha observado en algunos controladores JDBC? –

+0

Probaría esto también sin apostarlo ... o puede probar cargar datos en un conjunto de datos en .Net, buclearlo y ver si también tarda 2 minutos. interesante saber ... – Asken

+0

@ Adam, estoy seguro. Y como suponía, es el comportamiento predeterminado de los controladores JDBC. –

6

En mi experiencia, el controlador Oracle JDBC está mal configurado de fábrica para la transferencia masiva. Por defecto, solo transfiere 10 registros a través de la red a la vez. Por lo tanto, si tiene 1,000,000 de registros, el controlador incurrirá en 100,000 accesos de red.

Se puede decir que la ResultSet cuántos registros para ir a buscar a la vez con este código:

result.setFetchSize(1000); 

Siéntase libre de experimentar con diferentes tamaños. Ha reducido drásticamente el tiempo de procesamiento (de minutos a segundos) en al menos una aplicación en la que he trabajado.

Cuestiones relacionadas