31 억 행의 데이터를 관리하는 방법?


14

나는 현재 비교적 많은 양의 데이터에 대한 스토리지 스키마 구현을 맡고 있습니다. 데이터는 주로 현재 data point값 을 결정하기 위해 액세스 되지만 데이터 추세 / 분석에 대한 지난 6 개월의 기록을 추적해야합니다.

지난 1 시간 동안 의 min/ max/ sum값 을 추적하기 위해 최근 요구 사항이 추가되었습니다 .

참고 : 이상적으로는 MongoDB 옵션을 고려하고 싶지만 SQL-Server 옵션을 먼저 사용했음을 증명해야합니다.

자료

다음 표는 기본 데이터 소스 (가장 자주 쿼리 됨)를 나타냅니다. 테이블에는 약 5 백만 개의 행이 있습니다. 데이터 변경은 주로 초기 데이터로드 후 UPDATE매우 가끔씩 표시되는 INSERT명령문입니다. 나는 dataPointId당신이 항상 선택할 것이므로 데이터를 클러스터링하기로 결정했다 all values for a given data point.

// Simplified Table
CREATE TABLE [dbo].[DataPointValue](
    [dataPointId]  [int] NOT NULL,
    [valueId]      [int] NOT NULL,
    [timestamp]    [datetime] NOT NULL,
    [minimum]      [decimal](18, 0) NOT NULL,
    [hourMinimum]  [decimal](18, 0) NOT NULL,
    [current]      [decimal](18, 0) NOT NULL,
    [currentTrend] [decimal](18, 0) NOT NULL,
    [hourMaximum]  [decimal](18, 0) NOT NULL,
    [maximum]      [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointValue] PRIMARY KEY CLUSTERED ([dataPointId],[valueId])
)

두 번째 테이블은 약 31 억 행 (지난 6 개월 동안의 데이터를 나타냄)으로 현저히 큽니다. 6 개월이 지난 데이터는 제거됩니다. 그렇지 않으면 엄격하게 데이터 INSERT문 (~ 200 행 / 초, 720,000 행 / 시간, 1,700 만행 / 주)입니다.

// Simplified Table
CREATE TABLE [dbo].[DataPointValueHistory](
    [dataPointId] [int]            NOT NULL,
    [valueId]     [int]            NOT NULL,
    [timestamp]   [datetime]       NOT NULL,
    [value]       [decimal](18, 0) NOT NULL,
    [delta]       [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointHistory] PRIMARY KEY CLUSTERED ([dataPointId], [valueId], [timestamp])

)

추적 된 데이터 포인트 값의 수가 400 행 / 초로 증가함에 따라이 테이블의 크기가 두 배가 될 것으로 예상됩니다 (약 100 억에 도달하는 것은 문제가되지 않습니다).

The Question (s) (예, 하나 이상을 요청하고 있습니다. 모두 밀접하게 관련되어 있습니다).

현재 SQL-Server 2008 R2 Standard Edition 데이터베이스를 사용하고 있습니다. 테이블 파티션으로 원하는 성능 수준을 얻을 수 있다면 (또는 SQL-Server로 필요한 성능 수준에 도달 할 수없는 경우 MongoDB) Enterprise Edition으로 업그레이드 할 수 있습니다. 다음에 대한 귀하의 의견을 부탁드립니다.


1) min, maxsum지난 1 시간 동안 ( now - 60 minutes) 을 계산해야한다고 가정합니다 . 최근 데이터를 추적하는 가장 좋은 방법은 무엇입니까?

  • 최근 데이터를 데이터 서비스의 메모리에 보관하십시오. 각 데이터 UPDATE로 계산 된 최소 / 최대 / 평균을 씁니다.

  • 각 UPDATE 문 동안 히스토리 테이블에서 최근 히스토리를 조회하십시오 (다음 질문에 영향을 미칩니 까?). 쿼리는 데이터 포인트 값에 대한 최신 데이터에 액세스하고 지난 백만 레코드 정도만 스캔해야합니까?

  • 히스토리 테이블 조회를 피하기 위해 최근 히스토리를 DataPointValue 행에 저장 하시겠습니까? 아마도 구분 된 문자열로 저장되어 UPDATE proc 내부에서 처리됩니까?

  • 고려하지 않은 다른 옵션은 무엇입니까?


2)의 경우 DataPointValueHistory, datable에 대한 쿼리는 항상 dataPointId하나 이상의 쿼리 valueId입니다. 쿼리 된 데이터는 일반적으로 마지막 날, 주 또는 월에 대한 것이지만 경우에 따라 전체 6 개월에 대한 것일 수도 있습니다.

현재 dataPointId / valueId / timeStamp 또는 timeStamp / dataPointId / valueId로 클러스터링하는 것이 더 적합한 지 실험하기 위해 샘플 데이터 세트를 생성 중입니다. 누구 든지이 크기의 테이블을 다루는 데 경험이 있고 통찰력을 기꺼이 제공하려는 경우 감사하겠습니다. 인덱스 조각화를 피하기 위해 후자의 옵션에 기울고 있지만 쿼리 성능이 중요합니다.

  • DataPointValueHistorydataPointId-> valueId-> timeStamp 별 클러스터

  • 시간 DataPointValueHistory소인 별 클러스터 -> dataPointId-> valueId


3) 마지막으로 위에서 언급했듯이 DataPointValueHistory테이블 을 분할하는 것이 합리적이라고 생각 합니다. 히스토리 데이터를 가장 잘 분할하는 방법에 대한 제안은 크게 감사하겠습니다.

  • 타임 스탬프로 먼저 클러스터 된 경우 데이터를 주별로 분할해야한다고 생각합니다 (총 27 개의 파티션). 가장 오래된 파티션은 27 주 후에 제거됩니다.

  • dataPointId로 먼저 클러스터링 된 경우 데이터를 일부 모듈러스로 분할해야한다고 생각합니까?

테이블 파티셔닝에 대한 경험이 매우 제한적이기 때문에 귀하의 전문 지식에 감사드립니다.


이 질문의 버전을 StackOverflow에서 삭제 했습니까?
Taryn

@bluefeet-예, 주제를 벗어난 것으로 표시되었습니다 ... 그래서 SO 질문을 삭제하고 여기에서 다시 작성했습니다 (아마도 마이그레이션되기를 기다려야했을 것입니다).
캘거리 코더

문제 없습니다. 질문이 교차 게시되지 않았는지 확인했습니다.
Taryn

Standard Edition에서도 분할 된 뷰와 여러 기본 테이블을 사용하여 데이터를 분할 할 수 있습니다. 당신이 그것을 고려했는지 확실하지 않습니다.
Jon Seigel

@Jon-예, 수동 테이블 파티션을 고려했습니다 (특정 선택은 사용 가능한 Enterprise 라이센스가 있는지 여부에 따라 결정됩니다. 그렇다면, 왜 내 자신의 역할인지).
캘거리 코더

답변:


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.