2012-01-09 3 views
1

이것은 디자인/알고리즘 질문입니다. SQL 테이블이 너무 큽니다. 페이징/세그먼트 화를 통해 데이터를 검색합니까?

  • 내가 (., 말 5 백만 행) 큰 테이블이 데이터의 내가 자동차 그리고
  • 난을 수행하는 응용 프로그램을 가지고 전화 할게 : 여기 내 시나리오의 개요입니다 이 자동차에 SELECT * 테이블은 모든 데이터를 복용하고 단일 데이터 파일로 패키징 (후 어딘가에 업로드된다.)
  • 내 응용 프로그램에 의해 생성 된이 데이터 파일은 테이블이 순간 속에서 스냅 샷을 나타냅니다 제 시간에.
  • 테이블 그러나 자동차은 응용 프로그램이 현재 테이블에서 패키지를 생성하고 있는지 여부에 관계없이 다른 프로세스에서 산발적으로 업데이트됩니다. (현재의 동기가 없습니다.)

내 문제 :

이 테이블 자동차가에 대해 단일 SELECT *을 할 너무 큰되고있다. 내 애플리케이션이이 모든 데이터를 한 번에 가져 오면 내 컴퓨터의 메모리 용량을 빠르게 압도합니다 (2GB라고 가정). 또한 LIMIT 또는 OFFSET을 사용하여 체인을 실행하면 동기화 조건이 실패합니다. 테이블이 자주 업데이트되고 SELECT 호출간에 데이터를 변경할 수 없습니다.

내가을 찾고 있어요 :

무한대에 접근 할 수있는 데이터 크기를 가정하면, 그 메모리 용량 데이터보다 작은 응용 프로그램으로이 테이블의 전체를 당겨하는 방법. 특히 SQL select에 대해 페이지 매김/분할 효과를 얻으려면 어떻게해야합니까? 즉, 데이터의 다음 세그먼트를 검색하기 위해 페이지 번호가있는 되풀이 호출 만들기. 이상적인 솔루션은 데이터 크기의 확장 성을 허용합니다.

(내 시나리오를 단순화하기 위해, 우리는 그 다음 다음 세그먼트를 요청하기 전에 사용되는 메모리를 확보/쓰기 데이터의 세그먼트를 부여 할 때, 응용 프로그램이 처리 할 수 ​​있다고 가정 할 수 있습니다.)

어떤 제안 당신은 가장 도움이 될만한 것을 제공 할 수 있습니다. 감사!

편집 : 요청에 의해, 내 구현은 C# .NET 4.0 & MSSQL에게 2008 년

편집 # 2를 사용 이것은 SQL 명령 질문 없습니다. 이것은 디자인 패턴과 관련된 질문입니다. 대형 테이블에 대해 페이지 매김 된 SELECT를 수행하는 전략은 무엇입니까? (특히 테이블이 일관된 업데이트를받는 경우)

+1

우선 : 프로덕션 환경에서 'SELECT *'를 절대 사용하지 마십시오. –

+1

둘째 : ** 어떤 데이터베이스 **와 어떤 버전에 대해 이야기하고 있습니까? SQL은 많은 데이터베이스 시스템에서 사용되는 구조화 된 쿼리 언어 일뿐입니다. 우리가 아마도 당신을 도울 수는 없습니다. ..... 사용중인 데이터베이스 제품을 알아야합니다. –

+0

@marc_s : 당신은 그런 단언을한다. 일반적으로 동의하지만 'select *'가 유효한 상황이 있습니다. 예를 들어 결과를 사용하기 위해 dbreader의 메타 데이터를 읽는 경우입니다. –

답변

0

"스냅 샷"효과를 원한다면 데이터가 업데이트되지 않는 보관 용 테이블로 복사해야합니다. 다양한 유형의 변경 추적으로 좋은 것을 달성 할 수는 있지만, 그것은 당신이 원하는 바가 아닙니다. 정확한 테이블 상태의 스냅 샷이 필요한 경우 스냅 샷을 찍어 별도의 테이블에 기록하고 한도 및 오프셋 (또는 기타)을 사용하여 페이지를 만듭니다.

5 백만 행에서 수정해야 할 필요가있는 디자인 요구 사항이라고 생각합니다. 2000 명의 클라이언트가 모두 5 백만 행의 스냅 샷을 가지고 있다면 크기 문제가 발생하기 시작할 것입니다. 조심하지 마라.

+0

이것은 제가 찾고 있던 답변의 종류에 따라 분명히 많습니다. 사실, 5 백만 행을 선택하는 것은 병목 현상을 나타냅니다 ... 다행히도이 선택의 목적은 매우 드물게 수행되는 '전체 백업'에 더 가깝습니다. 테이블의 점증적인 변경 사항을 처리하기 위해 작은 changeset 패키지를 만드는 또 다른 프로세스가 있습니다. 답변 해 주셔서 감사합니다. –

1

어떤 데이터베이스를 사용하고 있습니까? MySQL의에서 예를 들어, 다음은 행 (40)로부터 시작하여 20 개 행을 선택할 것이다 그러나 이것은 MySQL의 전용 절입니다 :

select * from cars limit 20 offset 40 
+0

MySQL에서 작동하지만 다른 RDBMS에서는 작동하지 않습니다 ... OP가 무엇을 사용하고 있는지 확실하지 않습니다 ... –

+0

MSSQL 2008 사용. –

0

당신은 결과 데이터 파일의 형식의 세부 사항을 제공해야한다 (편집이 포스트 그레스는이를 허용 보인다) .형식에 따라이 MySQL을위한 어떤 응용 프로그램 코드를 포함 예로, 데이터베이스에 직접 가능할 수 : 등, Oracle의

SELECT * INTO OUTFILE "c:/mydata.csv" 
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' 
LINES TERMINATED BY "\n" 
FROM my_table; 

그것이 BCP 것 SQLSERVER/사이베이스에 대한 수출이있을 것

또는 데이터를 스트리밍하여 메모리에 모두 보관하지 않고도 앱 언어에 따라 달라질 수 있습니다. 페이징의 측면에서

는 쉬운 옵션은 한계 절을 사용하는 것입니다 (만약 mysql을) 또는 당신이 사용하는 어떤 RDBMS의 equivelent, 그러나 이것은 최후의 수단이다

select * from myTable order by ID LIMIT 0,1000 
select * from myTable order by ID LIMIT 1000,1000 
select * from myTable order by ID LIMIT 2000,1000 
... 

이이 선택 1000 행 청크로 된 데이터

+0

응답 해 주셔서 감사합니다. 불행히도이 데이터를 응용 프로그램에 가져 와서 추가 처리를 한 다음 행을 JSON 객체로 다시 매핑하므로 CSV 직접 내보내기가 여기에 도움이되지 않습니다. 대안은 무엇입니까? 저는 C# .NET 4.0과 MSSQL 2008을 사용하고 있습니다. LIMIT에서 프로그래밍 방식으로 선택하는 것은 페이지 매김에서도 직관적 이었지만보다 세련된 패턴을 원했습니다. –

+0

@Dave - 검색 한 후 데이터를 마사지하는 경우 데이터보기를 만들고 해당 데이터 조작을보기에 구현하는 것이 좋습니다. 보기를 원하는 결과와 정확히 일치 시키려면 표 대신이보기에 대해 Paul의 솔루션을 사용할 수 있습니다. –

+0

아, 안 좋은 생각입니다. 하지만 데이터를 마사지하는 것보다 조금 더 효율적이라고 말하면 안전합니다. 다듬어서 데이터 전송 객체 목록으로 구성하고 프로그래밍 방식으로 확인/정리 한 다음 큰 JSON 데이터 파일로 직렬화합니다. 모두 똑같은 흥미로운 아이디어를 제공합니다 ... 앞서 언급 한 OUTFILE을 사용하여 내 응용 프로그램에 FTP로 보내고 파일 스트림을 열고 한 번에 부품 만 읽고 청크로 데이터를 처리 할 수 ​​있습니다. 또한 .NET에서 SqlDataReader가 파일 전송 내용없이이 동일한 데이터의 버퍼링되지 않은 스트리밍을 제공한다고 들었습니다. –

0

한계와 오프셋을 사용하여 SQL 쿼리에서 페이지 매김 결과를 만들려면이 게시물을보십시오.

http://www.petefreitag.com/item/451.cfm

먼저해야 할 것 : 등등

SELECT * from Cars Limit 10 

다음

SELECT * from Cars limit 10 offset 10 

그리고있다. 당신은 이것을위한 최고의 페이지 매김을 알아 내야 할 것입니다.

+0

MySQL에서 작동하지만 다른 RDBMS에서는 작동하지 않습니다 ... OP가 무엇을 사용하고 있는지 확실하지 않습니다 ... –

+2

물론 대답은 질문만큼이나 좋을 수 있습니다;) –

+0

감사합니다; LIMIT 및 OFFSET 옵션을 알고 있지만 둘 중 어느 것도 요구하지 않습니다. 이 페이지 매김을 달성하기위한 전략을 찾고 있는데,이 옵션은 테이블이 지속적으로 업데이트된다는 경고와 함께이 옵션을 포함 할 수 있습니다. 이러한 SELECT간에 업데이트가 발생하고 전체 테이블을 선택하기 전에는 내 목표를 달성하지 못합니다. (내 '스냅 샷'조건을 참조하십시오.) –

관련 문제