programing

행 가져오기의 Oracle 크기를 더 높게 설정하면 앱 속도가 느려집니까?

lovejava 2023. 6. 18. 10:00

행 가져오기의 Oracle 크기를 더 높게 설정하면 앱 속도가 느려집니까?

여기에서 자세히 설명하고 여기에서 확인한 대로 JDBC를 통해 데이터를 쿼리할 때 Oracle이 반환하는 기본 행 수는 10개입니다.저는 우리 데이터베이스에서 많은 데이터를 읽고 비교해야 하는 앱을 만들고 있습니다.만약 우리가 더 늘면defaultRowPrefetch1000 정도가 되면 우리 앱이 더 빨리 작동할 것입니다.결과적으로, 그것은 더 느리고 약 20% 정도 성능이 떨어졌습니다.

그리고 나서 우리는 그 숫자를 10개에서 천천히 늘리기로 결정했고 그것이 어떻게 작동하는지 보기로 했습니다.100에서 200 사이로 설정함으로써 약 10%의 증가를 보았습니다.하지만 더 높게 설정하면 앱 성능이 더 느려질 것이라고는 전혀 예상하지 못했을 것입니다.왜 이런 일이 생길지 짐작 가는 게 있나요?

감사합니다!

편집:

설명을 위해 Oracle 11g R2와 Java 6을 사용하고 있습니다.

편집 2:

좋아요, 제 질문을 다시 한 번 분명히 말씀드리고 싶습니다. 왜냐하면 아래의 답변들로 미루어 볼 때, 저는 제 자신을 제대로 표현하지 못하고 있기 때문입니다.

가져오기 크기를 높게 설정하면 앱의 성능이 저하될 수 있는 방법은 무엇입니까?저에게 그것은 "우리는 더 빠른 인터넷 연결, 즉 더 두꺼운 파이프를 제공하지만, 당신의 웹 검색은 더 느릴 것입니다.

다른 모든 것이 동일하다는 점에서, 우리의 테스트에서도 그랬듯이, 우리는 우리의 앱이 어떻게 단 한 번의 변경만으로 더 나쁜 성능을 발휘할 수 있는지 매우 궁금합니다.

가능한 설명:

  1. Java는 아무것도 하지 않고 있으며 Oracle은 처음 10개가 아닌 처음 1000개의 행을 계산하고 있습니다.

  2. Oracle은 아무것도 하지 않는 반면 Java는 마지막 10개 행이 아닌 마지막 1000개 행을 계산합니다.

  3. 통신 프로토콜(예: TCP/IP)은 많이 대기한 다음 한 번에 더 많은 데이터를 처리해야 하지만 하드웨어 제한으로 인해 최대 데이터 전송 속도가 느려집니다.이는 프로토콜의 오버헤드에 의해 상쇄되므로 최적의 가져오기 크기가 있어야 하며 더 작거나 더 많은 것은 더 느립니다 ;)

  4. 가져오기 프로세스가 다른 Java 코드와 동기화되어 Java가 이전 데이터를 처리한 후에만 더 많은 행을 요청하고 Oracle은 그 동안 아무것도 하지 않으면 상황이 더 악화됩니다.

    세 명의 사람이 있다고 상상해 보십시오.

    • 첫번째는 A4용지를 반으로 접습니다.
    • 두 번째는 접힌 종이 더미를 한 방에서 다른 방으로 가져옵니다.
    • 세 번째는 접힌 종이에서 약간의 모양을 잘라냅니다.

    첫 번째 사람이 두 번째 사람이 돌아올 때까지 기다려야 하고 두 번째 사람이 세 번째 사람이 일을 마칠 때까지 기다려야 한다면 스택의 크기는 얼마나 되어야 합니까?

    1000개의 스택이 10개의 스택보다 낫지 않을 것입니다 ;)

것과 로, 든것마과지로가, 니다습없은 .FAST=TRUE설정JDBC 기본 가져오기 크기인 10은 상황에 적합하지 않지만, "일반적인" OLTP 애플리케이션에도 문제가 없으며, 귀하의 경우에도 그렇게 나쁘지 않은 것 같습니다.보아하니 큰 가져오기 크기도 상황에 적합하지 않습니다.하지만 한 번에 1000개씩 하는 것도 나쁘지 않습니다.

당신이 언급하지 않은 또 다른 요인은 얼마나 많은 행이 당겨지는지입니다.네트워크를 통해 데이터베이스 서버에서 앱 서버로 가져오는 데이터 덩어리는sum(WIDTH*ROWS)행이 5000바이트이고 한 번에 1000바이트를 풀링하는 경우 각 페치는 5MB의 데이터를 가져옵니다.다른 경우에는 행이 100바이트에 불과할 때 "마른" 것일 수도 있습니다.그 중 1,000개를 가져오는 것은 100,000개의 조각을 차단하는 것입니다.

사용자만 데이터가 반환되는 모습을 알 수 있으므로 "일반" 사례에 대해 시스템 전체의 가져오기 크기를 설정한 다음 필요에 따라 홀수볼 쿼리를 개별적으로 조정하는 것이 좋습니다.

일반적으로, 저도 100이 대규모 데이터 프로세스에 더 적합하다는 것을 알게 되었습니다.그것은 추천이 아니라 관찰 결과를 전달하는 것입니다.

참고로 Oracle 드라이버는 실제 데이터 크기가 아닌 각 행이 취할 수 있는 최대 크기를 위해 어레이를 따로 설정하므로 최소한 Oracle에서는 가져오기 크기에 주의해야 합니다.그래서 만약 여러분이 두꺼운 테이블을 가지고 있다면, 여러분의 기억력은 손상될 수 있습니다.

여기를 살펴보십시오 - http://www.oracle.com/technetwork/database/enterprise-edition/memory.pdf

Oracle에서는 user_tab_columns 메타데이터 테이블(data_length)의 열에 사용할 수 있는 최대 공간을 찾을 수 있습니다.가져오기 크기를 결정하는 데 사용할 수 있습니다.

대략적인 테스트를 통해 4 * 1024 * 1024 /sum(테이블의 모든 열에 대한 data_length)이 적절한 가져오기 크기임을 알게 되었습니다.

올바른 방법은 setFetchSize를 사용하는 것입니다.

기본적으로 Oracle JDBC는 쿼리를 실행할 때 데이터베이스 커서에서 한 번에 10개 행의 결과 집합을 검색합니다.기본 Oracle 행 가져오기 크기 값입니다.행 가져오기 크기 값을 변경하여 데이터베이스 커서로 이동할 때마다 검색되는 행 수를 변경할 수 있습니다.

또한 표준 JDBC를 사용하면 쿼리에 대해 각 데이터베이스 왕복으로 가져온 행 수를 지정할 수 있으며, 이 수를 가져오기 크기라고 합니다.Oracle JDBC에서는 행 프리페치 값이 문 개체의 기본 가져오기 크기로 사용됩니다.가져오기 크기를 설정하면 행 프리페치 설정이 재정의되고 해당 문 개체를 통해 실행되는 후속 쿼리에 영향을 줍니다.

가져오기 크기는 결과 집합에서도 사용됩니다.문의 개체가 쿼리를 실행하면 문의 개체의 가져오기 크기가 쿼리에 의해 생성된 결과 집합 개체로 전달됩니다.그러나 결과 집합 개체의 가져오기 크기를 설정하여 전달된 문 가져오기 크기를 재정의할 수도 있습니다.

Adam H.가 말한 것과 거의 같습니다 - 모든 유형의 시나리오에 대한 보편적인 설정은 없습니다.Oracle이 행을 가져오는 데 시간이 걸리기 때문에 클라이언트에 보내기 전에 서버 측 행을 기다리는 데 소요된 시간이 앱에서 미리 설정된 임계값보다 낮게 설정되어 있으면 성능이 저하될 수 있습니다.

또한 Oracle은 클라이언트 측 캐싱을 사용하여 스크롤 가능한 커서를 제공합니다.적어도 메모리 측면에서는 커서를 포워드로만 설정하는 데 도움이 될 수 있습니다.적어도 이전 버전의 JDBC 드라이버에서는 도움이 되었습니다. 아마도 그 이후로 동작이 바뀌었을 것입니다.

Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY);

daveslab, 정보 좀 더 많은 정보...

데이터 처리를 시작하는 데 전체 결과 집합이 필요한 경우 가져오기 크기가 클수록 향상될 수 있습니다.그러나 가장 유익한 값을 테스트하는 데 필요한 마법의 숫자는 없습니다.

프리페치 크기를 설정하면 응용프로그램의 성능에 영향을 줄 수 있습니다.프리페치 크기를 늘리면 모든 데이터를 가져오는 데 필요한 왕복 횟수는 줄어들지만 메모리 사용량은 증가합니다.이 값은 쿼리의 열 수와 크기, 반환될 것으로 예상되는 행 수에 따라 달라집니다.또한 JDBC 클라이언트 시스템의 메모리 및 CPU 로드에 따라 달라집니다.최적의 방법은 독립 실행형 클라이언트 응용프로그램이 부하가 높은 응용프로그램 서버와 다르다는 것입니다.네트워크 연결의 속도와 지연 시간도 고려해야 합니다.

Oracle JDBC 클라이언트는 전체 프리페치 크기를 유지하기 위해 일부 메모리 구조를 미리 초기화하는 것 같습니다. 따라서 프리페치 크기를 500으로 설정하면 프리페치 크기 = 10보다 50배 많은 메모리를 할당합니다.이것은 특히 당신이 실제로 그 행들을 읽지 않는다면 GC에 대한 엄청난 추가 요구입니다.일반적으로 몇 개의 행만 가져오면 GC 50x를 필요 이상으로 자주 실행할 수 있습니다. 이는 애플리케이션 응답성에 큰 영향을 미칠 것입니다.

가능하다면 쿼리 단위로 setFetchSize를 사용하는 것이 좋습니다.예를 들어, 특정 쿼리가 몇 개의 행만 반환한다는 것을 알고 있는 경우에는 가져오기 크기를 5로 설정합니다.쿼리가 1000개의 행을 반환한다는 것을 알고 있는 경우에는 100의 가져오기 크기를 사용합니다.

경험적 접근법으로서 50-100을 초과할 경우 얻을 수 있는 이점은 제한적입니다.

이해해주시길 바랍니다, 저는 구글 번역기를 사용하고 있습니다.

언급URL : https://stackoverflow.com/questions/9220171/setting-oracle-size-of-row-fetches-higher-makes-my-app-slower