2010-02-23 4 views
5

두 개의 PostgreSQL 데이터베이스에 많은 양의 데이터를 처리하기 위해 Perl 스크립트를 작성하고 있습니다 (총 4 천 2 백만 행이지만 총 1 행으로 완료되지는 않습니다).DBI의 fetchall_hashref와 fetchall_arrayref의 성능 차이는 무엇입니까?

내 검색어 중 일부의 경우 합성 키가 있기 때문에 fetchall_hashref을 사용하는 것이 좋습니다. 그러나 다른 경우에는 고유 한 키로 세 개의 열로 구성된 배열을 사용해야합니다.

이것은 성능 차이가 fetchall_arrayreffetchall_hashref 사이 인 것에 대해 궁금해합니다. 두 경우 모두 모든 것이 메모리에 저장되므로 몇 GB의 데이터를 선택하는 것은 좋은 생각이 아닐 수 있지만 성능면에서 문서에 거의 지침이없는 것으로 보입니다.

내 인터넷 검색 결과가 성공적이지 못해서 누군가가 일반적인 실적 연구의 방향으로 나를 지적 할 수 있다면 감사 할 것입니다.

(나는 이것을 스스로 벤치마킹 할 수 있지만 dev 목적으로는 불행히도 생산과 동일한 하드웨어를 가진 기계에 액세스 할 수 없다는 것을 알고있다. 그래서 나는 일반적인 지침이나 모범 사례를 찾고있다).

답변

3

첫 번째 질문은 이 실제로 일 때 fetchall을 사용해야한다는 것입니다. 한 번에 4200 만 줄의 메모리를 모두 필요로하지 않는다면 한번에 모두 읽지 마십시오! bind_columnsfetchrow_arrayref은 일반적으로 ysth가 이미 지적했듯이 가능할 때마다가는 길입니다.

fetchall 정말 필요하다고 가정하면, 내 직감 직감은 배열 간단한 데이터 구조 및 삽입 된 키의 해시를 계산하는 데 필요하지 않지만, 시간 절약이 될 것이기 때문 fetchall_arrayref가 빠른 소폭이 될 것입니다 데이터베이스 읽기 시간이 비하면 작아서 중요하지는 않습니다.

메모리 요구 사항은 완전히 다른 문제입니다. fetchall_hashref에 의해 반환 된 구조는 id => row의 해시이며 각 행은 field name => field value의 해시로 표시됩니다. 4 천 2 백만 행을 얻으면 필드 이름 목록이 4200 만 개의 해시 키 집합에서 반복된다는 것을 의미합니다. 즉, fetchall_arrayref에 의해 반환 된 배열 배열 배열보다 저장하기에 더 많은 메모리가 필요합니다. (fetchall_hashref 구조를 최적화하기 위해 DBI가 tie이라는 마법을 쓰지 않는다면, 나는 가정합니다.)

+0

감사합니다. 확실히 fetchall을 사용하여 다시 살펴보고 해시를 다시 고려해 보겠습니다. – azp74

5

fetch 메소드 간의 대부분의 선택 사항은 데이터가 끝내기를 원하는 형식과 DBI가 수행하고자하는 작업의 양에 따라 달라집니다.

내 기억은 fetchrow_arrayref를 반복하고 bind_columns를 사용하는 것이 반환 된 데이터를 읽는 가장 빠른 (가장 적은 DBI 오버 헤드) 방법이라는 것입니다.

+1

이것은 필자의 이해와 일치합니다. – fennec

+1

... 문서와 함께. http://search.cpan.org/~timb/DBI-1.609/DBI.pm#fetchrow_arrayref "이것은 특히 $ sth-> bind_columns와 함께 사용하는 경우 데이터를 가져 오는 가장 빠른 방법입니다." –

+0

편집자가이 질문 제목의 초점을 좁혔습니다. 내게는 그 질문이 전반적으로 그 좁은 초점을 가졌는지에 대해 모호한 것이었고 나는 더 일반적으로 대답하기를 선택했다. – ysth