2016-03-27 19 views
0

Bir toplu iş programı oluşturmaya çalışıyorum. Sorun şu ki, masa iki milyon sıraya sahip olabilir ve bu bir hafıza problemi yaratabilir. İşimde DB2 var ve evimde mysql kullandım.Limit numarası satırları olan ResultSet jdbc sürücüsü

Tutulma ile hata ayıklandı ettik ve bu sonuçları tüm satırları görüyorum.

Web sayfasında arama yaptım ama çözümü bulamadım. Örneğin, benim test kodu:

package misCodigos; 

    import java.io.FileWriter; 
    import java.io.IOException; 
    import java.sql.Connection; 
    import java.sql.DriverManager; 
    import java.sql.PreparedStatement; 
    import java.sql.ResultSet; 
    import java.sql.SQLException; 
    import java.sql.Statement; 

    public class testLimitDB { 

     // JDBC driver name and database URL 
     static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; 
     static final String DB_URL = "jdbc:mysql://localhost/testing"; 

     // Database credentials 
     static final String USER = "root"; 
     static final String PASS = "8182"; 


     private static FileWriter fw=null; 

     public static void main(String[] args) { 
      // Clase que pretende mostrar cómo insertar filas en java 
      Connection conn = null; 
      Statement stmt = null; 


      try{ 

       //STEP 2: Register JDBC driver 
       Class.forName("com.mysql.jdbc.Driver"); 

       //STEP 3: Open a connection 
       System.out.println("Connecting to database..."); 
       conn = DriverManager.getConnection(DB_URL,USER,PASS); 

       //STEP 4: Execute a query 
       // System.out.println("Creating statement..."); 
       stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, 
         java.sql.ResultSet.CONCUR_READ_ONLY); 
       String sql = "select * from tablaTest"; 


       PreparedStatement pstmt; 
       pstmt = conn.prepareStatement(sql); 

       conn.setAutoCommit(false); 
       pstmt.setFetchSize(200); 

       ResultSet rs = pstmt.executeQuery(sql); 
       System.out.println("Starting to retrieve data. Memory Used: " + getUsedMemorySize()); 

       //System.out.println(rs.getString(rs.last())); 

       /*   rs.last(); 
       int numRows = rs.getRow(); 
       System.out.println("Numero de filas: " + numRows);*/ 

       fw = new FileWriter("test.out"); 
       while (rs.next()) { 
        fw.write(rs.getInt(1) + ";" + rs.getString(2) + "\n"); 
       } 
       System.out.println("Done retrieving data => Memory Used: " + getUsedMemorySize()); 

       pstmt.close(); 
       conn.close(); 
       fw.flush(); 
       fw.close(); 

      }catch(Exception e){ 
       //Handle errors for Class.forName 
       e.printStackTrace(); 
      }finally{ 
       //finally block used to close resources 

       try{ 

        if (fw != null){ 
         fw.flush(); 
         fw.close();  
        } 

        if(stmt!=null) { 
         stmt.close(); 
        } 
       }catch(SQLException | IOException se2){ 
       }// nothing we can do 
       try{ 
        if(conn!=null) { 
         conn.close(); 
        } 
       }catch(SQLException se){ 
        se.printStackTrace(); 
       }//end finally try 
      }//end try 
      System.out.println("Finalizado!"); 


     } 

     public static long getUsedMemorySize() { 

      long freeSize = 0L; 
      long totalSize = 0L; 
      long usedSize = -1L; 
      try { 
       Runtime info = Runtime.getRuntime(); 
       freeSize = info.freeMemory(); 
       totalSize = info.totalMemory(); 
       usedSize = totalSize - freeSize; 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return usedSize; 

     } 

    } 

Could anyone help me? 

Teşekkür

PD: Ben db2 kodu yarattı. Sonuç kümesi, yalnızca sevdiğim satırları getirip getirmediğinden emin değilim çünkü tutulma modunda ve hata değişkeninde hata ayıklama modunu kullanarak, şimdi çok farklı ve şifreli görünüyor.

import java.io.FileWriter; 
import java.io.IOException; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 

public class testLimitDB { 

    // JDBC driver name and database URL 
    //static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; 

    static final String JDBC_DRIVER = "com.ibm.db2.jcc.DB2Driver"; 
    //static final String DB_URL = "jdbc:mysql://localhost/testing"; 
    static final String DB_URL = "jdbc:db2://localhost:50000/SAMPLE"; 

    // Database credentials MYSQL 
    //static final String USER = "root"; 

    static final String USER = "db2admin"; 
    static final String PASS = "8182"; 


    private static FileWriter fw=null; 

    public static void main(String[] args) { 
     // Clase que pretende mostrar cómo insertar filas en java 

     Connection conn = null; 
     Statement stmt = null; 


     try{ 

      //STEP 2: Register JDBC driver 
      Class.forName(JDBC_DRIVER); 

      //STEP 3: Open a connection 
      System.out.println("Connecting to database..."); 
      conn = DriverManager.getConnection(DB_URL,USER,PASS); 

      //STEP 4: Execute a query 
      // System.out.println("Creating statement..."); 
      stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, 
        java.sql.ResultSet.CONCUR_READ_ONLY); 
      String sql = "select * from FELIPE.TABLATEST"; 


      PreparedStatement pstmt; 
      pstmt = conn.prepareStatement(sql); 

      conn.setAutoCommit(false); 
      pstmt.setFetchSize(999); 

      ResultSet rs = pstmt.executeQuery(); 
      System.out.println("Starting to retrieve data. Memory Used: " + getUsedMemorySize()); 

      //System.out.println(rs.getString(rs.last())); 

      /*   rs.last(); 
      int numRows = rs.getRow(); 
      System.out.println("Numero de filas: " + numRows);*/ 

      fw = new FileWriter("test.out"); 
      while (rs.next()) { 
       fw.write(rs.getInt(1) + ";" + rs.getString(2) + "\n"); 
      } 
      System.out.println("Done retrieving data => Memory Used: " + getUsedMemorySize()); 

      pstmt.close(); 
      conn.close(); 
      fw.flush(); 
      fw.close(); 

     }catch(Exception e){ 
      //Handle errors for Class.forName 
      e.printStackTrace(); 
     }finally{ 
      //finally block used to close resources 

      try{ 

       if (fw != null){ 
        fw.flush(); 
        fw.close();  
       } 

       if(stmt!=null) { 
        stmt.close(); 
       } 
      }catch(SQLException | IOException se2){ 
      }// nothing we can do 
      try{ 
       if(conn!=null) { 
        conn.close(); 
       } 
      }catch(SQLException se){ 
       se.printStackTrace(); 
      }//end finally try 
     }//end try 
     System.out.println("Finalizado!"); 


    } 

    public static long getUsedMemorySize() { 

     long freeSize = 0L; 
     long totalSize = 0L; 
     long usedSize = -1L; 
     try { 
      Runtime info = Runtime.getRuntime(); 
      freeSize = info.freeMemory(); 
      totalSize = info.totalMemory(); 
      usedSize = totalSize - freeSize; 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return usedSize; 

    } 

} 

Tekrar denedim ve benim sonuçlar sürücüleri (MySQL ve DB2) düzgün çalışması vardır. Jvisualvm ile test ettim ve hafızanın imlecin büyüklüğüyle değiştiğini gördüm. Farklı sonuçlar içeren bir belge yazacağım ve onu göndereceğim.

+2

[Bu soru] (http://stackoverflow.com/questions/3885193/equivalent-of-limit-for-db2) nasıl yapılacağı hakkında konuşur db2'de. – azurefrog

+0

Muhtemel yinelenen [Tüm kayıtları büyük tablodan alırken OOM (Yetersiz bellek) hatası nasıl önlenir?] (Http://stackoverflow.com/questions/1107732/how-to-avoid-oom-out-of-memory -Toplam-tüm-kayıtları-büyük--tab-alırken kayıtları) –

+0

MySQL kullanır 'LİMİT' –

cevap

0

Sorununun, sunucu tarafı imleçleri bulunmayan ve büyük sonuç kümesini seçen MySQL ile test edilmesinin, FETCH boyutunu ayarlarsanız veya ayarlamamış olursanız olun OOM'a yol açması kaçınılmaz olduğunu düşünüyorum.

DB2, imleçler nedeniyle aynı soruna sahip değil ve sürücü OOM atmayacak. Uygun bir Fetch Boyutunu tanımlamanız gerekir. Büyük bir toplu işiniz varsa büyük bir değer kullanırdım. Başka bir deyişle, aynı ortama karşı test testi yaptığınızda :)

+0

Teşekkürler Alexandre! DB2'de test yapmayı deneyeceğim ve size bildireceğim. :) –

+0

Alexandre, behaivour'un doğru olup olmadığından emin değilim, çünkü sonuç kümesi mysql ve tüm alanların anlamsız harf olduğunu çok farklı. –

+0

Eğer OOM Mysql ile atar ve OOM DB2 ile atarsa, en azından OOM istisnasını düzeltmelidir. Öte yandan, nasıl hareket ettiği konusunda% 100 emin olmak istiyorsanız, örneğin, Sorgu İzleyicisi gibi DB2 için bir SQL izleme programı kullanabilirsiniz. Orada SQL'in nasıl yürütüldüğünü gözlemleyebilirsiniz. Alternatif olarak, kaç tane uzaktan arama yapıldığını görmek için ağ trafiğini koklayabilirsiniz, Getirme Boyutunu doğrulamak istiyorsanız budur. B –