programing

Oracle CLOB 성능

codeshow 2023. 9. 14. 23:43
반응형

Oracle CLOB 성능

CLOB(평균 20k 문자)를 검색하기 위해 JDBC로 Oracle 10g에 대한 쿼리를 실행하고 있습니다(최신 드라이버와 UCP를 DataSource로 사용).그러나 성능이 상당히 좋지 않은 것 같습니다. 100개의 LOB를 일괄 검색하는 데 평균 4초가 걸립니다.또한 제가 관찰한 바로는 I/O도 CPU도 네트워크도 아닙니다.

테스트 설정은 다음과 같습니다.

PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setConnectionFactoryClassName("...");
dataSource.setConnectionPoolName("...");
dataSource.setURL("...");
dataSource.setUser("...");
dataSource.setPassword("...");

dataSource.setConnectionProperty("defaultRowPrefetch", "1000");
dataSource.setConnectionProperty("defaultLobPrefetchSize", "500000");

final LobHandler handler = new OracleLobHandler();
JdbcTemplate j = new JdbcTemplate(dataSource);

j.query("SELECT bigClob FROM ...",

        new RowCallbackHandler() {

            public void processRow(final ResultSet rs) throws SQLException {

                String result = handler.getClobAsString(rs, "bigClob");

            }

        });

}

저는 페치 사이즈로 실험을 해보았지만 소용이 없었습니다.내가 뭘 잘못하고 있나요?JDBC를 사용할 때 CLOB 검색 속도를 높일 수 있는 방법이 있습니까?

결과 집합의 총 크기는 전체 검색 범위에 걸쳐 측정된 초기 비용 만 단위입니다.

쿼리에 Order By가 있습니까? 정렬해야 한다면 10K 행이 꽤 많습니다.

또한 PK를 검색하는 것은 전체 CLOB를 검색하는 것에 비해 공정한 테스트가 아닙니다.Oracle은 테이블 행 수가 많은 테이블 행을 블록에 저장하지만, 각 CLOB(4K 이상인 경우)는 일련의 블록에 대해 열외로 저장됩니다.따라서 PK 목록을 스캔하는 것이 빠를 것입니다.또한 PK에 인덱스가 있을 수 있으므로 Oracle은 인덱스 블록을 빠르게 검색하고 테이블에 액세스할 수도 없습니다.

4초는 조금 높은 것 같지만 디스크에서 읽을 수 있어야 하고 네트워크를 통해 Java 프로그램으로 전송해야 하는 2MB입니다.네트워크가 문제가 될 수 있습니다.세션의 SQL 추적을 수행하면 시간이 소비되고 있는 정확한 위치(디스크 읽기 또는 네트워크)를 알 수 있습니다.

오라클 LOB 타입의 데이터를 대용량 데이터를 저장하기 위해 사용했던 저의 과거 경험은 좋지 않았습니다.varchar2처럼 현지에 보관하기 때문에 4k 이하면 괜찮습니다.4k 이상이 되면 성능이 저하되기 시작합니다.아마 몇 년 전에 마지막으로 시도한 이후로 상황이 개선되었을 수도 있지만, 참고로 제가 과거에 발견한 것은 다음과 같습니다.

클라이언트가 오라클 서버를 통해 LOB를 받아야 하므로 다음과 같은 흥미로운 상황을 고려할 수 있습니다.

  • lob 데이터는 Oracle이 제한된 SGA 캐시를 캐시하기로 결정할 경우 다른 데이터 유형과 경쟁하게 됩니다.clob 데이터가 일반적으로 크기 때문에 다른 데이터를 푸시할 수 있습니다.
  • rob 데이터는 오라클이 캐시하지 않기로 결정한 경우 디스크 읽기가 불량해지고 클라이언트에 데이터를 스트리밍합니다.
  • 단편화는 아마도 아직 경험하지 못한 부분일 것입니다.응용프로그램이 lob을 삭제하고 Oracle이 lob을 재사용하려고 하는지 확인할 수 있습니다.오라클이 lob용 디스크 조각 모음을 온라인으로 지원하는지는 모르겠습니다(인덱스용은 있지만 이전에 시도했을 때는 시간이 오래 걸립니다)

당신은 avg 20k 100롭에 4s를 말씀하셨기 때문에 lob당 40ms입니다.각 로브는 별도의 로브 로케이터를 통해 검색해야 합니다(기본적으로 설정된 결과에는 없음).그건 각 로브에 대한 추가 왕복입니다, 제가 추측하기로는 (오래전이라 100% 확신할 수는 없습니다) 만약 그렇다면, 순차적으로 왕복 1회당 최소 5ms의 추가 시간이 소요될 것 같은데, 맞나요?그렇다면 성능은 이미 순차적 로브 페치에 의해 제한됩니다.sql 실행 vslob 컨텐츠 가져오기에 소요된 시간을 추적하여 이를 확인할 수 있어야 합니다.또는 게시물의 이전 답변에서 제시한 대로 lob 컬럼을 제외하여 확인할 수 있으며, lob 관련 여부를 알려줍니다.

행운을 빌어요

비슷한 문제가 있었는데 롭스에서 접속할 때 JDBC 롭스가 네트워크 통화를 하는 것을 발견했습니다.

Oracle 11.2g JDBC Driver부터는 프리페치를 사용할 수 있습니다.이것은 접속 속도를 10배나 높였습니다.

statement1.setFetchSize(1000);
if (statement1 instanceof OracleStatement) {
    ((OracleStatement) statement1).setLobPrefetchSize(250000);
}

도움이 되는 모든 제안에 감사드립니다.문제에 대한 답으로 표시되어 있음에도 불구하고, 제 대답은 좋은 해결책이 없는 것 같습니다.병렬문, 다양한 저장 특성, 정렬된 온도 테이블 등을 사용해 보았습니다.작업은 추적을 통해 볼 수 있는 특성이나 계획을 설명하는 데 구속되지 않는 것 같습니다.CLOB가 관련되어 있을 때 쿼리 병렬성조차도 개략적인 것처럼 보입니다.

의심할 여지 없이 11g 환경에서 대규모 CLOB(특히 압축)를 처리하는 데 더 나은 옵션이 있을 것입니다.10g 때문에 꼼짝 못합니다.

이제 CLOBs를 크기 최적화된 이진 RAW로 전처리할 데이터베이스에 대한 추가 왕복을 선택했습니다.이전 배포에서 이는 항상 매우 빠른 옵션이었으며 오프라인 계산 캐시를 유지하는 데 상당한 가치가 있을 것입니다.캐시가 무효화되고 누군가 더 좋은 아이디어를 생각해 낼 때까지 영구 프로세스와 AQ를 사용하여 업데이트됩니다.

언급URL : https://stackoverflow.com/questions/1525780/oracle-clob-performance

반응형