2014-11-17 2 views
-1

데이터베이스에 대해 쿼리를 실행 중이지만 제대로 작동하지만 테이블에 배치 할 데이터를 작성하는 데 다소 시간이 걸립니다. 나는 500,000 행의 데이터를 가져오고 있으며, 표시하는 데 시간이 오래 걸릴 것이라고 생각하지 않지만 내 응용 프로그램은 시간이 오래 걸리기 때문에 응답을 멈 춥니 다. 나는 다른 응용 프로그램에서 동일한 쿼리를 시도하고 정말 빠르게로드합니다. 내 속도를 높이기 위해 할 수있는 일이 있습니까?큰 MySQL ResultSet을 최적화하십시오.

public ArrayList<HashMap<String, ArrayList>> runQueries(String query){ 
    ArrayList<HashMap<String, ArrayList>> arrayList = new ArrayList<>(); 
    try{ 
     Statement stmt = conn.createStatement(); 
     stmt.execute(query); 
     while(true){ 
      HashMap<String, ArrayList> hm = new HashMap<>(); 
      // Get next resultset if no resultset was returned. 
      // The query was either an insert, update or delete 
      if(stmt.getUpdateCount() > -1){ 
       stmt.getMoreResults(); 
       continue; 
      } 
      // If the resultset is null exit 
      if(stmt.getResultSet() == null){ 
       break; 
      } 
      // We have a resultset! 
      // Save the columns to an array 
      // We can then display them later 
      ResultSet rs = stmt.getResultSet(); 
      int numColumns = rs.getMetaData().getColumnCount(); 
      ArrayList<String> columns = new ArrayList(); 
      for(int i = 0; i < numColumns; i++){ 
       columns.add(rs.getMetaData().getColumnName(i + 1)); 
      } 
      // Save the columns to the hashmap 
      hm.put("columns", columns); 

      // We now need to save the rows to an array as well 
      // We can then display them later as well 
      ObservableList<ObservableList<String>> oblist = FXCollections.observableArrayList(); 
      while(rs.next()){ 
       ObservableList<String> row = FXCollections.observableArrayList(); 
       for(int i = 1; i <= numColumns; i++){ 
        row.add(rs.getString(i)); 
       } 
       oblist.add(row); 
      } 
      ArrayList<ObservableList> rows = new ArrayList<>(); 
      rows.add(oblist); 
      rs.close(); 
      // Save the rows to the hashmap 
      hm.put("rows", rows); 
      // Save the hashmap to the final array 
      arrayList.add(hm); 
      stmt.getMoreResults(); 
     } 
    }catch(SQLException ex){ 
     Logger.getLogger(Mysql.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    return arrayList; 
} 

편집 : 실행하는 데 시간이 걸리는 부분으로 좁혀

:

ObservableList<ObservableList<String>> oblist = FXCollections.observableArrayList(); 
while(rs.next()){ 
    ObservableList<String> row = FXCollections.observableArrayList(); 
    for(int i = 1; i <= numColumns; i++){ 
     row.add(rs.getString(i)); 
    } 
    oblist.add(row); 
} 

답변

2

첫째 : 모든 레코드를로드하지 마십시오. 왜 그걸 할거야? 응용 프로그램에서 일종의 페이지 매김을 구현할 수 있습니다. 즉, 위의 '이전'및 '다음'과 '검색'입력란 아래에 두 개의 간단한 버튼을 추가하십시오. 처음에는 100 개의 레코드를로드합니다. 클릭 할 때마다 다음 100 개의 레코드를로드합니다. 사용자가 특정 레코드를 찾고 있다면 "검색"필드를 사용할 수 있습니다.

두 번째 : 백그라운드 스레드에서 레코드를로드하여 응용 프로그램 UI가 항상 응답하고 정지되지 않도록합니다. concurrency in JavaFX에 대해 더 자세히 읽어보십시오.

+0

 if(stmt.getUpdateCount() > -1){ stmt.getMoreResults(); continue; } if(stmt.getResultSet() == null){ break; } 

교체. 다른 프로그램은 필요한만큼 많은 데이터를로드 할 수 있으며, 경쟁하려면 동일한 것을 허용하고 싶습니다. HeidiSQL은 동일한 데이터 쿼리를로드하고이를 약 5 초 내에 테이블에 집어 넣습니다. –

+0

그런 다음 응용 프로그램을 "올바르게"수행하는 경우 응용 프로그램이 어떻게 정지됩니까? –

+0

'tableView.setItems (rows.get (0));'이 그것을 죽일 수 있습니까? FX 스레드에서 실행되는 ... –

0

보십시오이 백그라운드 스레드에서 실행 않습니다

 if(stmt.getUpdateCount() > -1){ 
      if (!stmt.getMoreResults()) { 
       break ; 
      } 
     } 
+0

결과 세트를 관찰 가능한 테이블로 변환하는 속도에는 아무런 영향을 미치지 않는다. 병목 현상이 될 수 있음). –

+0

main while 루프를 종료했는지 확인할 수 있습니까? 당신은 이전에 tableView.getItems()를 호출하는 단계에 도달하지 않는다고 말했습니다 ... –

+0

그래, 더 작은 쿼리의 경우 잘 동작합니다. 100k 행을 반환하는 쿼리를 수행하고 루프를 종료합니다. –

관련 문제