플래그 대 테이블 분할


10

나는 (잠재적으로) 수천만 개의 레코드를 포함 할 항목 테이블을 설계하고 있습니다. 일부 품목은 관리자가 "승인"할 때까지 사용할 수 없습니다. "사용"이란 해당 항목이 "승인"될 때까지 다른 테이블에서 참조되지 않음을 의미합니다. 상품의 최대 50 %는 언제든지 '비 승인'될 수 있습니다. 기록은 "승인"될 수 있지만 그 반대는 아닙니다.

두 가지 디자인 옵션을 고려합니다.

  • 비트 플래그
  • "승인되지 않은"품목의 별도 테이블-품목이 승인되면 "일반"테이블로 이동합니다 (항목 ID의 갱신은 문제가되지 않습니다)

두 번째 옵션이 훨씬 낫다고 생각합니다. 비트 플래그는 행당 바이트 만 사용하므로 문제가되지 않습니다. 그러나 동일한 테이블에 백만 개의 승인 된 레코드와 백만 개의 승인되지 않은 레코드가 있으면 승인 된 레코드가있는 작업의 스캔 시간이 늘어납니다.

질문은 : 대신 첫 번째 (비트 플래그) 옵션을 고려해야합니까? 설명 된 상황에서 이점이 있습니까?


1
필터링 된 인덱스를 사용하여 승인 된 레코드에 대한 액세스 속도를 높이는 데 도움이 될 수 있습니다. brentozar.com/archive/2013/11/…
mendosi

불행하게도 필터링 된 인덱스는 매개 변수화 된 쿼리에 사용되지 않습니다.
Dima

@Dima 그것은 전적으로 사실이 아닙니다. 필터링 된 인덱스에가 WHERE status='A'있고 쿼리에가 있으면 WHERE status = 'A' AND (... other columns and parameters here...)인덱스가 계속 사용될 수 있습니다.
ypercubeᵀᴹ

답변:


6

분할 된 뷰에서 두 가지 방법으로 사용할 수 있습니다 .

상호 배타적 인 값을 사용하여 제약 조건에 의해 시행되는 각 상태에 대한 기본 테이블을 만듭니다. 그런 다음 어떤 UNION이 기본 테이블을 함께하는지 확인하십시오. 뷰 또는 각 기본 테이블을 명시 적으로 참조 할 수 있습니다. 뷰를 통해 행의 상태가 갱신되면 DBMS는 하나의 기본 테이블에서 행을 삭제하고 새 상태에 해당하는 테이블에 삽입합니다. 각 기본 테이블은 사용 패턴에 따라 독립적으로 인덱싱 될 수 있습니다. 옵티마이 저는 가능하면 해당하는 단일 기본 테이블에 대한 인덱스 참조를 분석합니다.

장점은
a) 지수가 더 얕다는 것입니다. 그러나 인덱스 팬 아웃에 대한 계산을 수행하십시오. 해당 스케일과 상태 값 사이의 분할에서 인덱스는 결합 된 테이블에서와 동일한 분할 테이블에서 동일한 깊이가 될 수 있습니다.
b) 응용 프로그램 코드를 변경할 필요가 없습니다. 데이터는 계속해서 전체적으로 나타납니다.
c) 새로운 기본 테이블을 추가하고 제약 조건을 적용하고 뷰를 다시 생성하여 향후 새 상태 값을 포함 할 수 있습니다.

비용은 모든 데이터 이동입니다. 각 상태 업데이트마다 두 페이지와 관련 인덱스가 작성됩니다. 다루어야 할 많은 IO. 그렇게 많은 움직임도 조각화를 일으킬 것입니다.


5

(잠재적으로) 수천만 개의 레코드를 포함 할 항목 테이블.

SQL Server가 효율적으로 처리 할 수있는 것을 감안할 때 실제로 그렇게 많지는 않습니다. 물론 가장 큰 테이블 (단일 인스턴스 시스템) 중 하나에 200 만 개의 행이 있고 내가 처리 한 것 중 가장 큰 작업 중 하나를 기억합니다. 그런 다음 다음 작업에는 1 억 개의 행이있는 일부 테이블이있는 17 개의 프로덕션 인스턴스가 있었으며 모두 10 억 개가 넘는 행이있는 여러 팩트 테이블이있는 데이터웨어 하우스로 집계되었습니다. 잘못 이해하지 마십시오. 천만 행을 비웃지 않고 좋은 데이터 모델과 적절한 인덱싱 (및 인덱스 유지 관리)을 통해 SQL Server 가 많은 것을 처리 할 수 ​​있음을 강조하고 있습니다 .

상품의 최대 50 %는 언제든지 '비 승인'될 수 있습니다.

흠. 소리가 잘 들리지 않습니다. "승인"비율은 새로운 항목을 얻는 비율의 절반입니까? 2 개의 새로운 항목마다 1 개만 "승인"됩니까? 2 백만 개의 행과 각각 1 백만 개의 "승인 된"및 "비 승인 된"에 대해, 몇 년 후 다른 1 천만 개의 항목이있는 경우 "승인 된"및 "승인되지 않은"에 대해 각각 600 만 명을 예상하십니까? 또는 1 백만 "비 승인"이 다소 일정하게 유지되어 1000 만 개의 새 항목이 있으면 1 천 1 백만 "승인 됨"과 여전히 1 백만 "승인되지 않음"이 있습니까?

기록은 "승인"될 수 있지만 그 반대는 아닙니다.

오늘날에도 마찬가지 이지만 시간이 지남에 따라 상황이 바뀌므로 비즈니스에서 "비 승인"또는 "아카이브 된"등과 같은 다른 상태를 허용 할 가능성이 항상 있습니다.

선택 사항을 살펴 보겠습니다.

플래그 (또는 가능하면 TINYINT"상태")

  • 각 상태의 쿼리에 대해 약간 느리게
  • 시간이 지남에 따라 유연성이 향상되고 새로운 조회 상태 값만으로 세 번째 상태 (예 : "아카이브")와 같은 변경 사항을 쉽게 통합 할 수 있습니다. 새 테이블이 필요하지 않고 일부 새로운 코드가 있으며 일부 코드 만 업데이트되었습니다.
  • 더 적은 작업 (예 : 코드, 테스트 등) 및 단일 TINYINT열 업데이트 오류의 공간이 줄어 듭니다.
  • 덜 복잡함 = 시간이 지남에 따라 유지 보수 비용 절감, 신입 사원이 파악할 수있는 교육 시간 단축
  • 하나의 테이블이 업데이트 될 때 트랜잭션 로그에 미치는 영향이 적습니다.
  • 두 테이블 사이의 "RecordStatus"및 FK에 대한 조회 테이블 만 있으면됩니다.

두 개의 개별 테이블 (하나는 "승인 됨", 하나는 "비 승인 됨")

  • 각 상태의 쿼리에 대해 약간 더 빠름
  • 시간이 지남에 따라 유연성이 떨어지고 / 제 3 상태와 같은 변경을 통합하기가 더 어렵다 (예 : "아카이브"); 새로운 상태는 아마도 다른 테이블과 새로운 코드와 업데이트 된 코드를 요구할 것입니다.
  • 더 많은 작업 (예 : 코드, 테스트 등) 및 "승인되지 않은"테이블에서 "승인 된"테이블로 레코드를 이동하는 오류에 대한 더 많은 공간
  • 더 복잡한 = 시간이 지남에 따라 유지 관리 비용이 높고 신입 사원이 파악할 수있는 교육 시간이 길어짐
  • (아마도) 하나의 테이블이 삭제되고 하나가 삽입 될 때 트랜잭션 로그에 더 큰 영향
  • "걱정할 필요 항목의 ID의 갱신 "승인되지 않은 테이블은 인 ID 열이없는 IDENTITY열을 승인 테이블은 ID 열이 없습니다IDENTITY(그것이이 필요하지 않는 한). 따라서 레코드가 테이블간에 이동할 때 ID 값이 일관성을 유지합니다.

개인적으로, 나는 StatusID열이 있는 단일 테이블을 향해 몸을 기울 였습니다. 두 개의 테이블을 사용하는 것은 너무 복잡하고 조기에 최적화 된 것처럼 보입니다. 최적화의 유형을 논의 할 수 있습니다 때 경우 / 레코드의 수는 수백만의 수백에 색인 어떤 성능 향상을 제공하지 않습니다.


데이터가 빠르게 이동하는 테이블입니다. 많은 새 행으로 채워지고 행이 삭제되는 경우가 많습니다. 단일 주제에만 집중하기 위해 모든 세부 사항 (비즈니스 의사 결정, 클라이언트 코딩 등)을 제거하려고했습니다. 기본적으로 우리는 비트 플래그가있는 오래된 디자인 테이블을 가지고 있습니다. 그리고 플래그가 1로 설정된 행은 다른 테이블에서 사용되지 않는다는 것을 100 % 알고 있습니다. 그래서 나는 그들이 그곳에서만 일어나고 별도의 테이블로 옮겨 질 수 있다고 생각합니다. 테이블은 거의 모든 쿼리에서 DB로 스캔됩니다. 따라서 "무게"를 줄이면 CPU / IO 작동을 줄일 수 있습니다.
Dima

3
분할 테이블의 또 다른 장점 : "승인 된"테이블 만 참조하는 FK를 가질 수 있습니다.
ypercubeᵀᴹ

단일 엔터티에 대한 분할 테이블의 다른 문제는 제약 조건 무결성입니다. 다른 테이블의 참조는 레코드가 이동하는 데 적합하지 않습니다. 여기에는 분할 테이블에 대한 미러 참조 표를 기준으로이 문제를 해결하기 위해 작성하는 코드가 필요합니다 -> 아주 귀찮은
user1567453
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.