2013-12-16 1 views
11

나는 수백만 개의 행과 100 개 이상의 컬럼을 가진 Oracle 데이터베이스로 작업하고 있습니다. 특정 열을 인덱싱 한 pytables를 사용하여이 데이터를 HDF5 파일에 저장하려고합니다. 나는 팬더 DataFrame에서 이러한 데이터의 하위 집합을 읽고 계산을 수행 할 것입니다.오라클에서 수백만 행의 큰 테이블 읽기 및 HDF5 작성하기

내가 시도한 다음

다운로드 테이블, csv 파일로 유틸리티를 사용하여, 덩어리 사용 팬더하여 CSV 파일 청크를 읽고 pandas.HDFStore를 사용하여 HDF5 테이블에 추가합니다. dtype 정의를 작성하고 최대 문자열 크기를 제공했습니다.

그러나 Oracle DB에서 직접 데이터를 다운로드하고 pandas.HDFStore을 통해 HDF5 파일에 게시하려고 할 때 몇 가지 문제가 발생합니다.

pandas.io.sql.read_frame은 청크 읽기를 지원하지 않습니다. 전 메모리에 전체 데이터를 먼저 다운로드 할 수있는 충분한 RAM이 없습니다.

고정 된 수의 레코드로 cursor.fecthmany()을 사용하려고하면 DB 테이블에서 읽기 작업이 오래 걸리고 색인이 생성되지 않으며 날짜 범위 아래에있는 레코드를 읽어야합니다. 나는 DataFrame(cursor.fetchmany(), columns = ['a','b','c'], dtype=my_dtype) 을 사용하고 있지만 생성 된 DataFrame은 내가 제공 한 dtype을 적용하지 않고 항상 dtype을 유추합니다 (제공하는 dtype에 부합하는 read_csv와는 다릅니다). 따라서이 DataFrame을 이미 기존 HDFDatastore에 추가하면 유형 불일치가 발생합니다. 예 : float64는 하나의 청크에서 int64로 해석 될 수 있습니다.

당신이 생각을 제공하고 올바른 방향으로 나를 가리킬 수 있다면 감사하게 생각하십시오. 이 메모리 부족 작동을 위해 설계부터

+7

현재 접근 방식 (csv 사용) 및 dtype 수정이 적절합니다. SQL은 0.14에서 주요 업데이트를 얻게 될 것입니다 (0.13은 곧 출시 될 예정입니다). 따라서 불행히도 dtype infererence/chunking을 사용할 수 없습니다. PRS에 오신 것을 환영합니다! 이 문제를 참조하십시오 : https://github.com/pydata/pandas/issues/4163 – Jeff

+2

사물의 오라클 측면에 문제가 없다면 Oracle 태그를 제거하는 것이 좋습니다. –

+1

dba에게 테이블을 범위 파티셔닝 된 오브젝트로 변환하도록 요청해야합니다. 파티션으로 액세스하기 쉬워야합니다. – klashxx

답변

0

좋아, 그래서 오라클 데이터베이스와 많은 경험을 가지고 있지 않지만, 여기에 : : 팬더를 사용하여, 여기

오라클의 특정 레코드에 대한 액세스 시간은 색인 생성이 부족하고 시간 소인 순서로 데이터를 원하기 때문에 느립니다.

첫째, 데이터베이스에 대한 색인 생성을 활성화 할 수 없습니까?

데이터베이스를 조작 할 수없는 경우 각 행에 대해 순서가 지정된 고유 ID 만 포함하는 찾은 세트를 요청할 수 있습니까?

잠재적으로이 데이터를 고유 ID의 단일 배열로 저장할 수 있으며 메모리에 저장할 수 있어야합니다. 모든 고유 키 (보수적 인 추정치, 오버 헤드 등 포함)에 대해 4k를 허용하고 타임 스탬프를 유지하지 않으면 정수 배열이므로 3 백만 레코드에 대해 약 1.1GB의 RAM을 사용할 수 있습니다. 전체 힙이 아니며 활성 데이터가 작은 창만 필요하거나 행 단위로 처리하는 중일 것입니다.

이 모든 것을 수행하는 생성기 함수를 만듭니다.그렇게하면 일단 반복을 완료하면 메모리를 확보 할 수 있고, 아무 것도 할 필요가 없으며 코드를 더 쉽게 따르게되고 계산 루프의 실제 중요한 논리가 부풀어 오르는 것을 피할 수 있습니다.

메모리에 전체를 저장할 수 없거나 다른 이유로이 방법이 작동하지 않는 경우 수행 할 수있는 최선의 작업은 메모리에 저장할 수있는 양을 계산하는 것입니다. 잠재적으로 작업을 여러 요청으로 분할하고 데이터를 새 파일로 처리하는 동안 다중 스레드를 사용하여 마지막 작업이 완료된 후에 요청을 보낼 수 있습니다. 데이터를 반환 할 때까지 메모리를 사용하지 않아야합니다. 지연이 요청이 충족되거나 데이터가 다운로드되는 경우 시도하고 해결하십시오.

소리가 나면 데이터베이스를 추출하여 팬더가 요청하게 할 수 있습니다. 그것이 결과를 제한하는 방법을 살펴볼 가치가있을 것입니다. 모든 데이터를 요청할 수 있어야하지만 데이터베이스 서버에서 한 번에 한 행씩 결과를로드해야합니다.