복붙노트

[SQL] 오라클에서 스크립트를 통해 삽입하는 빠른 방법?

SQL

오라클에서 스크립트를 통해 삽입하는 빠른 방법?

나는 사용하여 Oracle 11g 데이터베이스 11.2.0.2.0을 ODP.NET 것을하는 C # .NET 4.0 응용 프로그램과 함께 일하고 있어요. 응용 프로그램 사전 부하 몇 룩업 데이터 테이블, 대부분의 이후이 적은 20 개 기록보다 스크립트가 꽤 빨리 실행합니다. 그러나, 스크립트 중 하나는 (802 개) 기록을 가지고 있으며, 많은 양의 데이터와 빠른 작업을 알리는 데이터베이스의 데이터와 같은 적은 양의 과도한 것 같다 레코드를 삽입 할 248.671 초 정도 걸립니다.

내가 궁금하네요 그래서, 데이터를 삽입 할 수있는 빠른 방법은 스크립트가 기록되는 현재의 방법보다, 스크립트를 통해,이?

테이블은과 같이 정의에 삽입 :

CREATE TABLE FileIds
(
     Id                 NUMERIC(38)                         NOT NULL
    ,Name               NVARCHAR2(50)   DEFAULT 'Unknown'   NOT NULL 
    ,FileTypeGroupId    NUMERIC(38)                         NOT NULL
    ,CONSTRAINT FK_FileIds_FileTypeGroups FOREIGN KEY ( FileTypeGroupId ) REFERENCES FileTypeGroups ( Id )
)

그리고 스크립트는 다음과 같습니다를 삽입 :

BEGIN
    INSERT ALL
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1152,5)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1197,10)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1200,6)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1143,3)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1189,9)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1109,7)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1166,4)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (0,8)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1149,2)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1400,1)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1330,11)
        INTO FileIds ( Id, FileTypeGroupId ) VALUES (1000,0)
        -- 790 Records removed for example purposes.
        SELECT * FROM DUAL;
    COMMIT;
END;

외래 키에서 참조 FileTypeGroups 테이블은, 이전 FileIds 테이블의로드에로드 된 사전이다. 거기 FileIds 테이블과 관련된 시퀀스 또는 트리거가없고, 아직 인덱스의 같은 테이블에 대해 생성되지 않았습니다.

해결법

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

    1.문제

    문제

    시간을 구문 분석하는 것은 특정 형식의 문의, 특히 INSERT ALL 기하 급수적으로 증가 할 수 있습니다. 예를 들면 :

    --Clear any cached statements, so we can consistently reproduce the problem.
    alter system flush shared_pool;
    alter session set sql_trace = true;
    
    --100 rows
    INSERT ALL
        INTO FileIds(Id,FileTypeGroupId) VALUES(1, 1)
        ...
        repeat 100 times
        ...
    select * from dual;
    
    --500 rows
    INSERT ALL
        INTO FileIds(Id,FileTypeGroupId) VALUES(1, 1)
        ...
        repeat 500 times
        ...
    select * from dual;
    
    alter session set sql_trace = false;
    

    TKPROF를 통해 추적 파일을 실행, 당신은 많은 수의 행에 대해 극적으로 구문 분석 시간이 증가를 볼 수 있습니다. 예를 들면 :

    100 행 :

    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.06       0.05          0          1          0           0
    Execute      1      0.00       0.00          0        100        303         100
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2      0.06       0.05          0        101        303         100
    

    500 행 :

    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1     14.72      14.55          0          0          0           0
    Execute      1      0.01       0.02          0        502       1518         500
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2     14.74      14.58          0        502       1518         500
    

    솔루션

    경고

    이에서 잘못된 교훈을 배울하지 마십시오. 당신이 SQL 성능에 대해 걱정하는 경우, 시간의 99 %는 비슷한 것들을 함께 대신에 떨어져 분할을 그룹화하는 것이 더 낫다. 당신이 일을 올바른 방법으로하고있어, 당신은 이상한 버그에 달렸다. (나는 내 ​​오라클 지원을 검색하지만,이 공식 버그를 찾을 수 없습니다.)

  2. from https://stackoverflow.com/questions/11656026/faster-way-to-insert-via-script-in-oracle by cc-by-sa and MIT license