2010-03-26 4 views
9

나는 blob 이미지를 저장하는 열과 함께 다소 큰 mysql 데이터베이스 (수백만 행)로 작업하고있다. 응용 프로그램은 이미지의 하위 집합을 가져오고 일부 처리 알고리즘을 실행합니다. 내가 가지고있는 문제는 내가 가지고있는 다소 큰 데이터 세트로 인해 내 쿼리가 반환하는 데이터 집합이 너무 커서 메모리에 저장할 수 없다는 것입니다.거대한 SQL 결과 다루기

당분간 이미지를 반환하지 않도록 쿼리를 변경했습니다. 결과 세트를 반복하면서 현재 레코드와 관련된 개별 이미지를 가져 오는 다른 select를 실행합니다. 이 방법은 효과가 있지만 수만 건의 추가 쿼리로 인해 성능이 저하 될 수 있습니다.

내 생각은 원래 쿼리를 10,000 개 결과로 제한 한 다음 10,000 개의 행을 걸쳐 쿼리를 계속 수행하는 것입니다. 이것은 두 접근법 사이의 도로 타협의 중간처럼 보입니다. 아마 내가 잘 모르는 더 나은 해결책이 있다고 생각합니다. 한 번에 거대한 결과 집합의 일부만을 메모리에 저장하는 또 다른 방법이 있습니까?

건배,

데이브 맥클 랜드

+0

아마 내 메모리 문제가 쿼리에 의해 발생하지 않습니다. 나는 오래된 버전 (감사, 버전 관리)으로 되돌아 갔고, 데이터 웨어레이터는 Anthony가 언급 한 것처럼 현재 읽고있는 행만로드하는 것으로 보입니다. DB 서버에서 네트워크를 통해 이미지를 전송하는 대신 로컬 파일 시스템에 이미지를 보관하는 것이 더 좋지 않은지 궁금합니다 (아래 ProphetBeal에서 언급했듯이). 단점은 두 위치 모두에 저장된다는 것입니다 (다른 시스템을 사용하기 위해서는 DB에 있어야합니다). 그러나 파일 시스템 저장 공간은 즉각적인 문제가 아닙니다. 이것에 대한 의견이 있으십니까? –

+0

Anthony는 DataReader가 내 메모리가 가득 채워진 이유가 아니라고 지적했기 때문에 Anthony에 대한 답을 제공합니다 (관련이 있지만 약간 다릅니다). ProphetBeal의 로컬 컴퓨터에서 BLOB를 유지하여 네트워크 정체를 제거하는 솔루션을 사용할 가능성이 있지만 로컬 컴퓨터에 저장할 데이터 세트를 다루는 모든 사람은 DataReader가 효과적인 솔루션이어야합니다. –

답변

3

하나의 옵션은 DataReader를 사용하는 것입니다. 데이터를 스트리밍하지만 데이터베이스에 대한 연결을 유지해야합니다. 수백만 행을 반복하고 각 행에 대해 처리를 수행하는 경우 바람직하지 않을 수 있습니다.

아마도 당신은 청크에서 데이터를 가져 오는 올바른 길을 가고 있다고 생각합니다. 아마도 MySql의 Limit 메서드를 사용했을 것입니다.

+0

예, SQL의 한계를 사용할 계획이었습니다. –

+0

또한, 이미 DataReader를 사용하여 OdbcCommand.ExecuteReader()를 사용하여 while (datareader.Read())을 반복하여 결과를 저장하고 있습니다. 사용 가능한 모든 시스템 메모리를 채우는 것처럼 매우 효율적으로 스트리밍되지 않는 것 같습니다. . 내가 모르는 데이터 보관함을 사용하고 있습니까? –

+0

@Dave, 다른 누군가가 datareader의 특정 메모리 사용량에 대한 통찰력을 제공 할 수는 있지만 메모리에 단일 레코드 만 있어야한다는 것이 이해됩니다 어떤 경우에도 DataSet 또는 DataTable보다 훨씬 적은 메모리 리소스가 필요합니다. 메모리 문제는 데이터를 검색 한 후에 수행 한 작업의 결과 일 수 있습니다. 그 객체들을 범위 내에서 유지하는 것. –

1

같은 대규모 데이터 세트를 처리하는 경우는 한 번에 메모리에 모든이 필요하지 않는 것이 중요합니다 . 결과를 디스크 나 웹 페이지에 쓰려면 각 행을 읽으면서 읽으십시오. 글을 쓰기 전에 모든 행을 읽을 때까지 기다리지 마십시오.

이미지를 DelayLoad = true으로 설정하여 직접이 기능을 구현하는 대신 필요한 경우에만 가져올 수 있습니다. 자세한 내용은 here을 참조하십시오.

+0

제가 언급 했어야 할 것은 (현재) ADO.NET을 사용하고 있다는 것입니다. DelayLoad와 동일한 기능이 있습니까? Linq로 마이그레이션 할 수는 있지만 선호하지는 않습니다. 질문 태그를 업데이트하겠습니다. 또한 결과를 어디에도 쓰지 않을 것입니다. 결과에 대한 이미지 분석 알고리즘을 실행하여 함수에 전달 된 이미지와 비교합니다. 결과적으로 최상의 이미지 만 저장하고 나머지는 무시할 수 있습니다. 빠른 답장을 보내 주셔서 감사합니다. –

0

2 가지 옵션이 있습니다.

1) 웹 응용 프로그램과 달리 Windows 응용 프로그램 인 경우 데이터 리더를 사용하여 각 이미지를 읽고 디스크의 임시 폴더에 파일을 덤프 할 수 있습니다. 그러면 필요한 모든 처리를 수행 할 수 있습니다. 실제 파일에 대해

2) 작은 청크로 데이터를 읽고 처리하십시오. 이미지의 크기와 수행하려는 프로세스의 양에 따라 10k 행이 여전히 많을 수 있습니다. 한 번에 5k 개의 행을 반환하고 처리하기 위해 남아있는 1k로 내려갈 때 별도의 스레드에서 더 많은 내용을 읽으면 원활한 프로세스를 만들 수 있습니다.

항상 권장되는 것은 아니지만 다음 행 집합을 처리하기 전에 가비지 수집을 강제하면 메모리를 확보하는 데 도움이 될 수 있습니다.

0

내가 사용했습니다 전에이 자습서에 설명 된 것과 같은 솔루션 : http://www.asp.net/(S(pdfrohu0ajmwt445fanvj2r3))/learn/data-access/tutorial-25-cs.aspx

먼저 1-10,000과에 끌어에서 다음 몇 가지 데이터 세트의 일부를 (미리 당겨 멀티 스레딩을 사용할 수

백그라운드가 10,001 - 20,000 및 20,001 - 30,000 행을 가져오고 데이터의 이전 페이지를 삭제합니다 (문제가있는 경우 메모리를 절약하기 위해 처음 50,000 ~ 60,000 개가 처음 1-10,000 행을 삭제한다고합시다). 사용자의 다음 데이터 범위를 가져 오거나 일부 범위를 벗어나는 데이터를 삭제하는 포인터로 현재 "페이지"의 위치.