문제

한 테이블에서 데이터를 선택하고 다른 테이블에 삽입해야합니다. 현재 SQL은 다음과 같습니다.

   INSERT INTO A (x, y, z)
   SELECT x, y, z
   FROM B b
   WHERE ...

그러나 일부는 선택이 크기 때문에 2 백만 행 이상을 초래하며 너무 많은 메모리를 차지하고 있다고 생각합니다. 이 경우 DB 인 Informix는 쿼리가 실행될 때 가상 메모리가 부족합니다.

행 세트를 선택하고 삽입하는 방법 (2000)은 어떻게해야합니까? 행 ID 등이 있다고 생각하지 않는다는 점을 감안할 때

도움이 되었습니까?

해결책

테이블에서 첫 번째 n *을 선택할 수 있습니다. 여기서 n은 원하는 행의 양입니다. 다음에 진술이 실행되면 이미 삽입 된 데이터가 포함되지 않습니다.

다른 팁

이것이 실행 된 스크립트가 있다고 가정합니까? 중첩 된 선택에서 반환 된 값을 주문하는 한 루프를하고 제한 할 수 있습니다. 여기 몇 가지 의사 코드가 있습니다.

total = SELECT COUNT(x) FROM B WHERE ...
while (total > 0) 
  INSERT INTO A (x, y, z) SELECT x, y, z FROM B b WHERE ... ORDER BY x LIMIT 2000
  total = total - 2000
end

IDS는 데이터를 클라이언트에게 반환하는 첫 번째 조항 만 사용할 수 있다고 확신합니다.1, 그리고 그것은 가능한 경우 피하고 싶은 것입니다.

당신은 당신이 메모리에서 오류가 발생하지 않는다고 말합니까 (예를 들어 긴 트랜잭션 중단 오류가 아니라)? 합리적인 양의 메모리가 있는지 확인하기 위해 서버의 구성을 살펴 보셨습니까?

데이터 세트가 얼마나 큰지, 제약 조건이 무엇인지 - 테이블에서로드를 수행하는 이유에 따라 다릅니다. 그러나 나는 일반적으로 데이터를로드 가능한 서브 세트로 분할하는 방법을 결정하고 루프에서 순차적으로 실행하는 것을 목표로합니다. 예를 들어, 시퀀스 번호가 1에서 10,000,000 사이 인 경우 루프를 10 번 실행할 수 있으며 시퀀스 번호로 조건이 있습니다. AND seqnum >= 0 AND seqnum < 1000000' and then및 Seqnum> = 10000000 및 Seqnum <2000000 '등. 바람직하게는 변수를 통해 범위를 대체 할 수있는 언어로.

이것은 약간 성가신 일이며, 범위 크기 측면에서 보수적 인 측면에서 오류를 원합니다 (더 큰 파티션이 아닌 더 작은 파티션 - 메모리가 부족할 위험을 줄입니다).


1 과도하게 단순화. 저장된 절차는 예를 들어 '클라이언트'로 계산되어야하며, 저장된 절차의 커뮤니케이션 비용은 진정한 클라이언트에게가는 비용보다 훨씬 적습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top