2014-12-10 3 views
1

며칠 전 메모리 컴퓨팅 프레임 워크를 사용하여 일부 처리 성능 테스트를 만들어야했습니다. 그래서 이것을 수행하기 위해 다양한 성능 테스트를 통해 점진적으로 증가 된 큰 데이터 풀이 필요했습니다.왜 PreparedStatement가 Statement보다 훨씬 빠릅니까?

DB는 오라클이며 22 개의 필드로 구성된 테이블을 포함하고 있습니다. 이 테이블은 1 mil 레코드에서 100 mil 레코드까지 점진적으로 채워 져야했습니다.

테이블을 1 mil로 채우기 위해 무작위 테스트 데이터를 생성하고 java Statement를 사용하여 DB에 삽입했습니다. 이는 17 및 16 초 분입니다. 그 후 100 밀 레코드 테이블을 채우려면 영원히 걸릴 것임을 알았 기 때문에 PreparedStatement로 시도 했으므로 조금 더 빠름을 알았으므로 차이는 매우 큽니다. 1 분 24 초 웹의 뒤쪽에있는 이유를 찾기 시작했고 몇 가지 이유를 발견했지만 내 생각에이 영향을 미쳐야합니다. LINK

된 PreparedStatement가 데이터베이스에서 컴파일 된 사전 도착하고 거기 액세스 계획이 또한 데이터베이스 캐시, 준비된 문을 사용하여 데이터베이스를 작성 파라 메트릭 쿼리를 실행할 수 있습니다 :

이 차이를 설명 할 수있는 그 무엇을 내가 찾은입니다 할 일이 적어 일반 쿼리보다 훨씬 빠릅니다. 프로덕션 JDBC 코드에서 PreparedStatement를 사용하여 데이터베이스의로드를 줄여야합니다. 성능을 얻으려면 SQL 쿼리의 매개 변수화 된 버전 만 사용하고 문자열 연결은 사용하지 않는 것이 좋습니다.

but 모든 데이터가 무작위로 생성되었으므로 oracles 측에서 주요 캐싱은 포함되어서는 안됩니다.

+3

오라클의 하드 및 소프트 구문 분석 및 SGA에 대해 읽어보십시오. 하드 파싱을 위해 준비되지 않은/리터럴 버전의 삽입물에 사용되는 처리주기가 많습니다. – OldProgrammer

+0

변경하기 전과 후에 프로그램을 추적하는 것이 좋습니다. 검사가 공정한 지 확인하십시오. 그런 다음 결과 추적 파일을 프로파일하십시오. 결과는 종종 놀랍습니다. – jeff6times7

답변

3

Oracle은 아마도 명령문 캐시에 쿼리 계획을 캐시 할 수 있습니다. 오라클 데이터베이스 JDBC 개발자 가이드 Implicit Statement Caching, 당

당신이 암시 문 캐싱을 사용

, JDBC는 자동으로이 문 개체의 close 메소드를 호출 준비된 또는 호출 문을 캐시합니다. 준비된 문과 호출 가능한 문은 표준 연결 개체 및 문 개체 메서드를 사용하여 캐시되고 검색됩니다.

암시 적 명령문 캐싱이 SQL 문자열을 키로 사용하고 일반 문이 SQL 문자열없이 작성되기 때문에 일반 문이 암시 적으로 캐시되지 않습니다. 따라서 암시 적 명령문 캐싱은 SQL 문자열로 생성되는 OraclePreparedStatementOracleCallableStatement 객체에만 적용됩니다.

+0

그래, 그럼, 쿼리 계획을 캐시 말할 수 있습니다,하지만 여전히 삽입 당 22 무작위 필드를 가지고, 그 다음 총 삽입 문장의 절반 ... – aurelius

+3

하지만 당신은 전체 쿼리를 보내지 않습니다; 그냥 쿼리 ID (및 필드). 쿼리 * 플러스 * 필드가 아닙니다. 그런 다음 캐싱을 추가하십시오. –

+0

PreparedStatement가 닫히는 곳이 보이지 않습니다.누군가가 동일한 SQL을 사용하여 Prepared Statement를 닫고 다시 여는 경우 암시 적 캐싱이 큰 도움이 될 수 있음을 분명히 이해합니다. 그러나 PreparedStatement 샘플은 준비된 명령문의 표준 구현처럼 보입니다 (한 번 명령문을 보냅니다. 그런 다음 각 쿼리에 대한 매개 변수를 보냅니다). 내가 여기 뭔가를 놓친 적이 있니? –

관련 문제