2012-08-23 14 views
8

Tôi đang đọc 1 triệu bản ghi từ Oracle DB bằng .Net và Java. Trong. Net Tôi đang sử dụng ODP.Net, trong Java client ojdbc6 mỏng. Trong. Net đọc dữ liệu mất khoảng 10 giây, và trong Java phải mất gần 2 phút. Tại sao có sự khác biệt lớn như vậy?Đọc dữ liệu từ Oracle DB bằng .Net nhanh hơn 10 lần so với sử dụng Java

Đây là một mã số:

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() đã làm công việc, cảm ơn.

+3

chỉ đoán: trong java bạn đang sử dụng chỉ là một JDBC-lái xe với "bất kỳ mức độ", trong .net một khách hàng bản địa chuyên dùng ... nhưng, nói chung, .net là nhanh hơn;) – TheHe

+2

Tôi nghĩ bạn đang bắt đầu với một tiền đề không hoàn thiện: Java có thể nhanh chóng. –

Trả lời

8

Trong Java theo mặc định, ResultSets được truy xuất hoàn toàn và được lưu trữ trong bộ nhớ. Điều này không tốt cho các truy vấn có ResultSets lớn. Để sử dụng kết quả được truyền trực tiếp, bạn phải sử dụng:

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

Tôi chưa so sánh thời gian, nhưng tôi đoán điều này sẽ nhanh hơn nhiều.

+0

Bạn có chắc rằng ResultSets được truy xuất hoàn toàn và được lưu trong bộ nhớ không? Đây có phải là một phần của tiêu chuẩn JDBC hay là hành vi này mà bạn đã quan sát trên một số trình điều khiển JDBC? –

+0

Tôi cũng sẽ thử điều này mà không đặt cược vào nó ... hoặc bạn có thể kiểm tra để tải dữ liệu vào tập dữ liệu trong .Net, lặp lại và xem liệu nó cũng mất 2 phút. thú vị để biết ... – Asken

+0

@Adam vâng tôi chắc chắn. Và như bạn đoán, đó là hành vi mặc định của các trình điều khiển JDBC. –

6

Theo kinh nghiệm của tôi, trình điều khiển JDBC Oracle được định cấu hình kém ngoài hộp để truyền khối lượng. Theo mặc định, nó chỉ chuyển 10 bản ghi trên mạng tại một thời điểm. Do đó, nếu bạn có 1.000.000 hồ sơ, người lái xe sẽ phải chịu 100.000 lượt truy cập mạng.

Bạn có thể nói với ResultSet bao nhiêu hồ sơ để lấy tại một thời điểm với mã này:

result.setFetchSize(1000); 

Hãy thử nghiệm với các kích cỡ khác nhau. Nó đã giảm đáng kể thời gian xử lý (từ phút đến giây) trong ít nhất một ứng dụng tôi đã làm việc trên.

Các vấn đề liên quan