[SQL] 더 : FOR 커서 루프 또는 간단한 선택 오라클 데이터베이스에 대량 삽입?
SQL더 : FOR 커서 루프 또는 간단한 선택 오라클 데이터베이스에 대량 삽입?
어느 Oracle 데이터베이스에 대량 삽입을위한 더 나은 옵션이 될 것인가? 같은 FOR 커서 루프
DECLARE
CURSOR C1 IS SELECT * FROM FOO;
BEGIN
FOR C1_REC IN C1 LOOP
INSERT INTO BAR(A,
B,
C)
VALUES(C1.A,
C1.B,
C1.C);
END LOOP;
END
또는 간단한은, 같은 선택 :
INSERT INTO BAR(A,
B,
C)
(SELECT A,
B,
C
FROM FOO);
특정 이유는 둘 중 하나가 더 나은 것입니까?
해결법
-
==============================
1.커서가 더 오래 걸릴 때문에 선택 옵션을 추천 할 것입니다. 또한, 선택은 당신의 쿼리를 수정하는 누군가를 위해 이해하기 훨씬 쉽게되어 사용
커서가 더 오래 걸릴 때문에 선택 옵션을 추천 할 것입니다. 또한, 선택은 당신의 쿼리를 수정하는 누군가를 위해 이해하기 훨씬 쉽게되어 사용
-
==============================
2.단일 SQL 문을 사용하는 대신, 당신이해야 PL / SQL을 사용하여 할 수 있다면 일반적인 경험 법칙이다. 그것은 일반적으로 더 효율적입니다.
단일 SQL 문을 사용하는 대신, 당신이해야 PL / SQL을 사용하여 할 수 있다면 일반적인 경험 법칙이다. 그것은 일반적으로 더 효율적입니다.
당신은 (어떤 이유로)보다 절차 적 로직을 추가해야하는 경우, 당신은 PL / SQL을 사용해야 할 수도 있습니다,하지만 당신은 행 단위 처리 대신 대량 작업을 사용해야합니다. (참고 : 오라클 10g 이상에서, 당신을위한 루프가 자동으로 한 번에 100 개의 행을 가져 COLLECT BULK를 사용하지만 사용자 삽입 문이 아직 완료 행에 의해 행됩니다).
EG
DECLARE TYPE tA IS TABLE OF FOO.A%TYPE INDEX BY PLS_INTEGER; TYPE tB IS TABLE OF FOO.B%TYPE INDEX BY PLS_INTEGER; TYPE tC IS TABLE OF FOO.C%TYPE INDEX BY PLS_INTEGER; rA tA; rB tB; rC tC; BEGIN SELECT * BULK COLLECT INTO rA, rB, rC FROM FOO; -- (do some procedural logic on the data?) FORALL i IN rA.FIRST..rA.LAST INSERT INTO BAR(A, B, C) VALUES(rA(i), rB(i), rC(i)); END;
위에서 언급 한 콘텍스트를 최소화하는 이점이 SQL 및 PL / SQL를 전환 갖는다. 오라클 11g는 또한 각 열에 대해 별도의 PL / SQL 테이블이 필요가 없습니다 그래서 기록의 테이블에 대한 더 나은 지원을하고있다.
데이터의 양이 매우 큰 경우 또한, 일괄 적으로 데이터를 처리하는 코드를 변경할 수 있습니다.
-
==============================
3.롤백 세그먼트 / 실행 취소 세그먼트는 트랜잭션의 크기를 수용 할 수있는 경우 다음 옵션이 더 낫다. 당신이 필요로하는 롤백 능력이 있고 롤백 / 실행 취소 세그먼트 너무 작은 에러가 발생하지 않도록 작은 커밋에 큰 삽입을 깰이없는 경우 옵션 1에 유용합니다.
롤백 세그먼트 / 실행 취소 세그먼트는 트랜잭션의 크기를 수용 할 수있는 경우 다음 옵션이 더 낫다. 당신이 필요로하는 롤백 능력이 있고 롤백 / 실행 취소 세그먼트 너무 작은 에러가 발생하지 않도록 작은 커밋에 큰 삽입을 깰이없는 경우 옵션 1에 유용합니다.
-
==============================
4.당신의 두번째 옵션이 훨씬 바람직하다 같은 간단한 인서트 / 선택합니다. 1 옵션에서 각 삽입을 위해 당신은 PL / SQL을 SQL에서 컨텍스트 스위치가 필요합니다. 추적 / TKPROF 각을 실행하고 결과를 검토합니다.
당신의 두번째 옵션이 훨씬 바람직하다 같은 간단한 인서트 / 선택합니다. 1 옵션에서 각 삽입을 위해 당신은 PL / SQL을 SQL에서 컨텍스트 스위치가 필요합니다. 추적 / TKPROF 각을 실행하고 결과를 검토합니다.
마이클 언급으로, 롤백 명령문을 처리 할 수 없습니다, 경우 다음 DBA는 더 당신을 줄 수 있습니다. 다중 패스에 데이터를 삽입에서 오는 부분적인 결과는 잠재적으로 매우 비싼 반면 디스크, 저렴합니다. (거의 취소 삽입과이 연결되지 않습니다.)
-
==============================
5.이 질문에 하나 개의 중요한 정보가 누락되어 있다고 생각합니다.
이 질문에 하나 개의 중요한 정보가 누락되어 있다고 생각합니다.
당신은 얼마나 많은 레코드를 삽입 할 것인가?
-
==============================
6.당신이 다른 답변을 읽어 볼 수 있듯이, 사용할 수있는 옵션이 많이 있습니다. 그냥 <10,000 행을하고 있다면 당신은 두 번째 옵션으로 가야한다.
당신이 다른 답변을 읽어 볼 수 있듯이, 사용할 수있는 옵션이 많이 있습니다. 그냥 <10,000 행을하고 있다면 당신은 두 번째 옵션으로 가야한다.
즉, 약> 10,000 모든 방법에 대해 <100,000 대답. 그것은 회색 영역의 종류이다. 오래된 괴짜의 많은 큰 롤백 세그먼트에서 껍질 것입니다. 그러나 정직하게 하드웨어와 소프트웨어를 사용하면 코드 만 몇 번을 실행하면 당신이 기록의 많은에 대한 옵션이 멀리 얻을 수있을 수있는 위치에 놀라운 진전을 만들었습니다. 그렇지 않으면 당신은 아마 모든 1K-10K 또는 행 그래서를 저지해야한다. 여기 내가 사용하는 조각이다. 좋아 나는 그 짧은 내가 커서를 선언 할 필요가 없기 때문에. 게다가 그것은 수집 및 FORALL 대량의 장점을 가지고있다.
begin for r in (select rownum rn, t.* from foo t) loop insert into bar (A,B,C) values (r.A,r.B,r.C); if mod(rn,1000)=0 then commit; end if; end; commit; end;
좀 더 자세히 옵션을 보여 오라클 사이트에서이 링크를 발견했다.
-
==============================
7.당신이 사용할 수있는:
당신이 사용할 수있는:
바인딩 대량이라고 수집 FOR ALL과 함께 대량.
PL / SQL FORALL 운영자는 빠른 간단한 테이블 삽입에 대한 30 배 속도 때문입니다.
BULK_COLLECT 및 Oracle FORALL이 두 가지 기능은 벌크 바인딩으로 알려져있다. 벌크 귀속 모든 작업은 대량으로, 한 번에 수행, 테이블에서의 UPDATE 또는 DELETE 문에서 검색을 실행하는 대신 여러 개의 개별 SELECT, INSERT,의, PL / SQL 기술, 또는 데이터를 저장합니다. 이 컨텍스트를 전환 방지 한 번에 할 때 개별적으로 접근 행 하나 인 PL / SQL 엔진이 등 뒤로 PL / SQL 엔진에 다음의 SQL 엔진에 이상 통과해야하고, 경우에 당신이 얻을. INSERT, UPDATE 및 DELETE 문으로 벌크 바인딩을 수행하려면, 당신은 PL / SQL FORALL 문 내에서 SQL 문을 묶습니다. SELECT 문으로 벌크 바인딩을 수행하려면, 대신 INTO를 사용하는 SELECT 문에서 BULK COLLECT 절을 포함한다.
그것은 성능을 향상시킵니다.
-
==============================
8.나는 데이터의 일일 완전한 재 장전을 위해 둘 다 할 수 없습니다. 예를 들어 내 덴버 사이트를 로딩하고 말한다. 거의 실시간 델타 다른 전략이있다.
나는 데이터의 일일 완전한 재 장전을 위해 둘 다 할 수 없습니다. 예를 들어 내 덴버 사이트를 로딩하고 말한다. 거의 실시간 델타 다른 전략이있다.
나는이 대량로드처럼 거의 빨리 내가 찾은으로 테이블 SQL을 만들어 사용 A는 CREATE TABLE 문 아래 예를 들어, 필요한 올바른 데이터 형식으로 열을 주조, 데이터를 준비하는 데 사용됩니다 :
표 sales_dataTemp 선택 등을 CREATE SALES_QUARTER로 주조 (날짜로 1 열) SALES_IN_MILLIONS로 주조 (번호 등 판매) .... 에서 1 번 테이블;
이 임시 테이블 거울 내 목표 테이블의 구조는 정확히 사이트에서 분할 된 목록이다. 그때 덴버 파티션과 파티션 스왑을하고 나는 새로운 데이터 세트가 있습니다.
from https://stackoverflow.com/questions/987013/bulk-insert-into-oracle-database-which-is-better-for-cursor-loop-or-a-simple-s by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 얼마나 멀리 정상화를 취할? [닫은] (0) | 2020.06.25 |
---|---|
[SQL] 서버 나 클라이언트에 정렬? (0) | 2020.06.25 |
[SQL] TSQL - 그것은 정렬 순서를 정의 할 수 있습니까? (0) | 2020.06.25 |
[SQL] SQL 서버 2008 R2에 대한 Try_Convert (0) | 2020.06.25 |
[SQL] OLE DB 공급자 연결된 서버 "Microsoft.ACE.OLEDB.12.0" "(널)" (0) | 2020.06.25 |