2013-04-05 3 views
4

나는 MySQL 데이터베이스를 쿼리하는 데 사용되는 매개 변수를 얻기 위해 HashMap을 반복해야하는 Java 프로그램이 있습니다.동일한 선택 쿼리를 여러 매개 변수로 여러 번 실행 : MySQL

Iterator<Entry<String, Double>>it = ws.entrySet().iterator(); 
Connection con = null; 

while(it.hasNext()) 
{ 
    Entry<String, Double>pairs = it.next(); 
    PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word=?"); 
    ps.setString(1, pairs.getKey()); 
    ResultSet rs = ps.executeQuery(); 
} 

반복 (약 500 배) 루프의 모든 반복에 대한 데이터베이스에 액세스하는 과정이 내 응용 프로그램을 늦추고 다음과 같이 코드입니다. 한 번에 데이터베이스에 액세스 할 수 있도록 이러한 모든 매개 변수를 보낼 수있는 방법이 있습니까?

+0

당신은 임시 테이블을 만들 수를하고'pairs.getKey()가'그 안에 값이 다음 사용 저장 'JOIN' 문은 테이블과 임시 테이블을 사용하여 데이터를 검색합니다. 물론 임시 테이블을 사용할 때 임시 테이블을 삭제하는 것을 잊지 마십시오 (RDBMS가 처리하지 못하는 경우). –

+0

쿼리가 느려 집니까? 프로세싱 루프가 대부분의 시간을 소비하는 곳은 어디입니까? – dcernahoschi

+1

읽어보기 : [JDBC의 선택 문 일괄 처리] (http://www.javaranch.com/journal/200510/Journal200510.jsp#a2) – informatik01

답변

1

지도가 WS이다 고려할 때, 당신은 그런 식으로 단일 쿼리를 수행 할 수 있습니다

Connection con = getConnection(); 
Set<String> ks = ws.keySet(); 

if (ks.size() > 0) { 
    StringBuilder inStatement = new StringBuilder("?"); 
    for (int i = 1; i < ks.size(); i++) { 
     inStatement.append(", ?"); 
    } 

    PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word in (" + inStatement.toString() + ")"); 

    int k = 1; 
    for (String key : keySet) { 
     ps.setString(k++, key); 
    } 
    ResultSet rs = ps.executeQuery(); 
} 
+0

RDBMS는 이러한 종류의 쿼리에서 성능이 떨어집니다. 항상'id =? '를 사용하는 것이 더 좋습니다. 또는 id =?'연결. 아직도, 'JOIN'은 이러한 모든 대안보다 훨씬 낫습니다. –

+0

'id =가 아닌가요? 또는 id =?'및'id in (?,?)'와 동일합니까? 어쨌든 어떻게 조인이 도움이 될지 모르겠다. ... – blint

+0

아니야. –

0

명령문을 한 번 준비하고 반복하고 매개 변수를 설정 한 다음 실행하십시오. 이 javadoc의

또는 IN 매개 변수를 미리 컴파일 할 수없는 및 PreparedStatement 객체에 저장 SQL 문에서입니다. 이 오브젝트는 을 사용하여이 명령문을 여러 번 효율적으로 실행할 수 있습니다. 이 f}은 프리 D 파일로부터 이익을 얻는 매개 변수식 SQL 문을 처리하기 위해 최적화됩니다. 드라이버가 프리 컴파일을 지원하는 경우 ...

Iterator<Entry<String, Double>>it = ws.entrySet().iterator(); 
Connection con = getConnection(); 

PreparedStatement ps = con.prepareStatement("select doc_freq from lookup where word=?"); 
while(it.hasNext()) 
{ 
    Entry<String, Double>pairs = it.next(); 
    ps.setString(1, pairs.getKey()); 
    ResultSet rs = ps.executeQuery(); 
} 

좋아, 나는 그것을 설명 할 것이다. 쿼리가 db로 컴파일되면 결과를 하나씩 실행하고 검색하는 것이 더 빠릅니다. 이는 여러 매개 변수가있는 쿼리 하나를 실행하는 것과 같습니다. 성능은 동일합니다. 그러나 당신이 준비하는 경우 동일한 SQL 쿼리를 여러 유형으로 컴파일하면 쿼리를 컴파일 할 때마다 db가 실행 계획을 작성하게됩니다. 이것은 시간이 많이 걸립니다. 이것이 바로이 테크닉이 문서에서 효율적이라고 부르는 이유입니다. 이 용어는 또한 Explain plan으로 알려져 있으며 쿼리를 더 잘 최적화하기 위해 db에 의해 생성됩니다.

+0

이 테스트를 통해 처리 시간이 단축되지는 않습니다. –

+0

@LuiggiMendoza 컴파일 시간을 저장합니다. –

+0

예이 시도했지만 처리 시간을 향상시키는 것 같지 않습니다 – jayanth

0

느린 이유는 분명하지 않지만 일반적인 문제 중 하나는 각 트랜잭션의 오버 헤드입니다.

innodb_flush_log_at_trx_commit을 0 또는 2로 설정하면 모든 것이 빨라집니다. ACID를 준수하는 유일한 설정은 기본값 인 1입니다. 대부분의 셋업에서 2는 완벽한 값입니다.

set global innodb_flush_log_at_trx_commit = 2; 
관련 문제