복붙노트

[SQL] CLOB에 SUBSTR의 성능

SQL

CLOB에 SUBSTR의 성능

나는 VARCHAR2 파라미터에 SUBSTRs을 많이 수행하는 PL / SQL 프로 시저가 있습니다. 내가 CLOB으로 변경하려고, 그래서 나는 길이 제한을 제거하고 싶습니다.

좋은 작품,하지만 몇 가지 테스트를했다 있도록 성능을 안고있다가, (2005 년부터이 시험 기준).

업데이트 : 다른 오라클 버전과 다른 하드웨어와 함께 몇 가지 다른 경우에이 문제를 재현 할 수있는, dbms_lob.substr이 눈에 띄게 느린 SUBSTR (CLOB)보다 항상, 그리고 많은 느린 SUBSTR (VARCHAR2) 이상.

밥의 결과와 링크의 테스트는 위의 다른 이야기.

사람이, 또는 적어도 재현 하나 밥의 또는 내 결과를 설명 할 수 있습니까? 감사!

시험 결과:

테스트 코드 :

DECLARE
  l_text   VARCHAR2(30) := 'This is a test record';
  l_clob   CLOB := l_text;
  l_substr VARCHAR2(30);
  t TIMESTAMP;
BEGIN
  t := SYSTIMESTAMP;
  FOR i IN 1..100000 LOOP
    l_substr := SUBSTR(l_text,1,14);
  END LOOP;
  dbms_output.put_line( SYSTIMESTAMP - t || ' (VARCHAR2)');

  t := SYSTIMESTAMP;
  FOR i IN 1..100000 LOOP
    l_substr := SUBSTR(l_clob,1,14);
  END LOOP;
  dbms_output.put_line( SYSTIMESTAMP - t || ' (CLOB SUBSTR)');

  t := SYSTIMESTAMP;
  FOR i IN 1..100000 LOOP
    l_substr := DBMS_LOB.SUBSTR(l_clob,14,1);
  END LOOP;
  dbms_output.put_line( SYSTIMESTAMP - t || ' (DBMS_LOB.SUBSTR)');
END;

해결법

  1. ==============================

    1.(거짓말, 빌어 먹을 거짓말, 그리고 벤치 마크 ...)

    (거짓말, 빌어 먹을 거짓말, 그리고 벤치 마크 ...)

    나는 긴 전체 30 자했다 그래서 문자열을 확장, 테스트 10 번 - 실행 다시, 다음과 같은 평균 결과를 얻었다 :

    +000000000 00:00:00.011694200 (VARCHAR2)
    +000000000 00:00:00.901000600 (CLOB SUBSTR)
    +000000000 00:00:00.013169200 (DBMS_LOB.SUBSTR)
    

    그때 5,14 (DBMS_LOB.SUBSTR에 대한 14.5)에 문자열 범위를 변경하고 있어요 :

    +000000000 00:00:00.011731000 (VARCHAR2)
    +000000000 00:00:01.010840000 (CLOB SUBSTR)
    +000000000 00:00:00.011427000 (DBMS_LOB.SUBSTR)
    

    그때 17,14 (DBMS_LOB.SUBSTR에 대한 14,17)와 GOT의 범위를 변경

    +000000000 00:00:00.013578900 (VARCHAR2)
    +000000000 00:00:00.964527400 (CLOB SUBSTR)
    +000000000 00:00:00.011416800 (DBMS_LOB.SUBSTR)
    

    마지막으로, 나는 25,14 (DBMS_LOB.SUBSTR에 대한 14,25)와 GOT의 범위를 변경

    +000000000 00:00:00.011210200 (VARCHAR2)
    +000000000 00:00:00.916439800 (CLOB SUBSTR)
    +000000000 00:00:00.013781300 (DBMS_LOB.SUBSTR)
    

    내 결론은 CLOB에 대해 작업 할 때 "정상"VARCHAR2에 대해 SUBSTR을 사용하는 것에 비해 효율적으로 성능 저하가 나타나는대로 DBMS_LOB.SUBSTR를 사용하는 것이 가장 좋습니다 점이다. CLOB로에 대한 SUBSTR 상당한 성능 저하로 고통 보인다. OS = HP / UX (유닉스 변종), 오라클 버전 = 11.1, 프로세서 = HP 아이테니엄 2 플렉스 - 기록하십시오. YMMV.

    공유하고 즐길 수 있습니다.

    그리고 그것의 가치는 그것의 가치가 과도하게 일을하고있는 경우 때문에, 여기에 32767 개 문자 확장 문자열과 좀 더 결과입니다. 결과의 각 세트와 함께 제공 범위를 하위 문자열 :

    1, 25000
    +000000000 00:00:00.198466400 (VARCHAR2)
    +000000000 00:00:02.870958700 (CLOB SUBSTR)
    +000000000 00:00:00.174490100 (DBMS_LOB.SUBSTR)
    
    1000, 25000
    +000000000 00:00:00.253447900 (VARCHAR2)
    +000000000 00:00:02.491790500 (CLOB SUBSTR)
    +000000000 00:00:00.193560100 (DBMS_LOB.SUBSTR)
    
    10000, 25000
    +000000000 00:00:00.217812000 (VARCHAR2)
    +000000000 00:00:02.268794800 (CLOB SUBSTR)
    +000000000 00:00:00.222200200 (DBMS_LOB.SUBSTR)
    

    같은 날, 같은 결론.

    크 툴루는 fhtagn.

    (위반에게 더 친애하는 친구 한 번, 한 번 더 ...)

    3,276,700에 CLOB의 크기를 변경하고, 길이 25000에 대한 2475000에서 중간 시작에서 문자열을 고려하여 벤치 마크를 재 - 실행 내가 얻을 :

    +000000000 00:00:00.176883200 (VARCHAR2)
    +000000000 00:00:02.069482600 (CLOB SUBSTR)
    +000000000 00:00:00.175341500 (DBMS_LOB.SUBSTR)
    

    (주 변화는 마지막 두 시험에 영향을 미친다).

    그리고 ... 같은 결과, 다른 일.

    YMMV.

  2. ==============================

    2.스크립트 다음과 같은 시스템에서 세 번 실행 :

    스크립트 다음과 같은 시스템에서 세 번 실행 :

    오라클 데이터베이스 11g 엔터프라이즈 에디션 출시 11.1.0.7.0 - 64 비트 생산

    여기 결과는 :

    +000000000 00:00:00.007787000 (VARCHAR2)
    +000000000 00:00:03.093258000 (CLOB SUBSTR)
    +000000000 00:00:00.340017000 (DBMS_LOB.SUBSTR)
    
    +000000000 00:00:00.019460000 (VARCHAR2)
    +000000000 00:00:03.302425000 (CLOB SUBSTR)
    +000000000 00:00:00.336915000 (DBMS_LOB.SUBSTR)
    
    +000000000 00:00:00.007773000 (VARCHAR2)
    +000000000 00:00:03.210619000 (CLOB SUBSTR)
    +000000000 00:00:00.336689000 (DBMS_LOB.SUBSTR)
    
  3. ==============================

    3.나는 11gR1 시험에 DBMS_LOB.substr 위해 부드럽게 실행되었는지 볼 수 있지만, 11gR2의 기능이 느립니다.

    나는 11gR1 시험에 DBMS_LOB.substr 위해 부드럽게 실행되었는지 볼 수 있지만, 11gR2의 기능이 느립니다.

    AIX6에 64 비트 생산 - 오라클 데이터베이스 11g 엔터프라이즈 에디션 출시 11.2.0.3.0에 내 테스트 아래.

    +000000000 00:00:00.009440000 (VARCHAR2)
    +000000000 00:00:00.749113000 (CLOB SUBSTR)
    +000000000 00:00:01.177685000 (DBMS_LOB.SUBSTR)
    
  4. ==============================

    4.나는 이것이 아주 오래 알고 있지만, 여전히 오래된 시스템에 사람들이 관련 될 수있다. 이 모습은 데이터 형식 변환 문제를 좋아한다. 뭔가를 바탕으로 내가 bernhard.weingartner 톱 @ 효과를보고 눈치, 오프셋 및 양 인수의 데이터 유형은 큰 차이를 만들 것으로 보인다.

    나는 이것이 아주 오래 알고 있지만, 여전히 오래된 시스템에 사람들이 관련 될 수있다. 이 모습은 데이터 형식 변환 문제를 좋아한다. 뭔가를 바탕으로 내가 bernhard.weingartner 톱 @ 효과를보고 눈치, 오프셋 및 양 인수의 데이터 유형은 큰 차이를 만들 것으로 보인다.

    이 단지 더 확실한 차이를 만들기 위해 만 반복 리눅스 (OEL 5.6)에 11.2.0.3에서 실행하고, 증가 :

    DECLARE
      l_text   VARCHAR2(30) := 'This is a test record';
      l_clob   CLOB := l_text;
      l_substr VARCHAR2(30);
      t TIMESTAMP;
    BEGIN
      t := SYSTIMESTAMP;
      FOR i IN 1..1000000 LOOP
        l_substr := SUBSTR(l_text,1,14);
      END LOOP;
      dbms_output.put_line( SYSTIMESTAMP - t || ' (VARCHAR2)');
    
      t := SYSTIMESTAMP;
      FOR i IN 1..1000000 LOOP
        l_substr := SUBSTR(l_clob,1,14);
      END LOOP;
      dbms_output.put_line( SYSTIMESTAMP - t || ' (CLOB SUBSTR)');
    
      t := SYSTIMESTAMP;
      FOR i IN 1..1000000 LOOP
        l_substr := DBMS_LOB.SUBSTR(l_clob,14,1);
      END LOOP;
      dbms_output.put_line( SYSTIMESTAMP - t || ' (DBMS_LOB.SUBSTR with 14,1)');
    
      t := SYSTIMESTAMP;
      FOR i IN 1..1000000 LOOP
        l_substr := DBMS_LOB.SUBSTR(l_clob,14.0,1.0);
      END LOOP;
      dbms_output.put_line( SYSTIMESTAMP - t || ' (DBMS_LOB.SUBSTR with 14.0,1.0)');
    
      t := SYSTIMESTAMP;
      FOR i IN 1..1000000 LOOP
        l_substr := DBMS_LOB.SUBSTR(l_clob,cast(14 as number), cast(1 as number));
      END LOOP;
      dbms_output.put_line( SYSTIMESTAMP - t || ' (DBMS_LOB.SUBSTR with casts)');
    END;
    /
    
    +000000000 00:00:00.043019000 (VARCHAR2)
    +000000000 00:00:03.671621000 (CLOB SUBSTR)
    +000000000 00:00:05.704337000 (DBMS_LOB.SUBSTR with 14,1)
    +000000000 00:00:00.040097000 (DBMS_LOB.SUBSTR with 14.0,1.0)
    +000000000 00:00:00.040907000 (DBMS_LOB.SUBSTR with casts)
    

    11gR2의 문서 유형의 정수로 형식 매개 변수를 보여 주지만, 명시 적으로 숫자가 빠르게 통과하면서 실제로 느린 정수를 통과 (또는 pls_integer, 또는 BINARY_DOUBLE).

    원래 질문 Bob의에서 11.1와 11.2 사이에 변경 뭔가 같은이 모습을 발생합니다. 나는 다시 변경된 경우 모르는 등등 시험에 12C 인스턴스가 없습니다. 이 DBMS_LOB의 변화 또는 PL / SQL은 기본적으로 숫자 값을 처리하는 방법에 대한 폭 넓은 변화 때문인지 명확하지 않다. 나는 관련 보이는 MOS에서 아무것도 발견하지 않았습니다.

  5. from https://stackoverflow.com/questions/10331912/performance-of-substr-on-clob by cc-by-sa and MIT license