비트 열에 인덱스를 추가하면 삽입 속도가 크게 저하됩니까?


11

약 1 백만에서 5 백만 개의 레코드가있는 테이블이 있습니다. 해당 레코드의 작은 부분에는 비트 열 중 하나가 'TRUE'로 설정되어 있습니다. 그 기록을 빨리 찾아야합니다. 인덱스 가이 열에서 검색 속도를 높일 수 있다고 생각하지만 INSERT가 두렵습니다. 따라서 내 질문.

데이터베이스는 일종의 데이터웨어 하우스처럼 작동하므로 많은 SELECT가 있고 작지만 (하루 최대 10-20 개) 매우 큰 INSERT (한 번에 최대 2 억 개의 레코드)가 있습니다. 데이터베이스로 가져 오는 데 더 오랜 시간이 걸릴까 걱정됩니다.


5
어떤 버전의 SQL Server입니까? 2008+가 필터링 된 인덱스처럼 들리면 필요할 수 있습니다.
Martin Smith

SQL Server 2005
marioosh

1
테이블을 분할 할 수 있습니다 (테이블의 PK 인 단 하나의 열만있는 새 테이블을 추가하십시오.이 열은 비트 열이 참인 행으로 채워집니다. 결국에는 비트 열을 제거 할 수도 있습니다). 2005 년에도 부분 인덱스가 부족한 상태에서도 뷰가 작동합니다.
ypercubeᵀᴹ

인덱싱 된 뷰를 충분히주의하십시오. 하루에 10-20 개의 큰 인서트가 있다고 언급 했으므로 인덱싱 된 뷰를 유지 관리하면 성능 향상의 이점을 능가 할 수 있습니다. SQL 2005의 "기본 제공 기능"은 상황을 개선하는 데 활용할 수 있다고 생각하지 않습니다. 그러나 현재 테이블 구조와 기존 인덱스를 나열하면 다른 디자인을 찾을 수 있습니다.
Anup Shah

답변:


8

백만 개의 레코드에 대한 인덱스는 쓸모가 없습니다. 옵티마이 저는 절대로이를 사용하지 않으며 유지 보수 비용 만 지불하면됩니다. 더 나은 대안은이 비트를 클러스터 된 인덱스에서 가장 왼쪽 키로 추가하는 것입니다.

그러나 나는 어둠 속에서 블라인드 샷을 만들고 큐 패턴이라고 생각합니다. 비트가 'TRUE'(예 : 'needsprocessing = true')로 설정된 테이블에서 레코드가 삭제되고 백그라운드 프로세스가 보입니다. 이러한 레코드의 경우 일부 처리를 수행하고 비트를 FALSE로 업데이트합니다. 이것은 전능 한 패턴이며 '성능 재난 레시피 패턴'으로도 잘 알려져 있습니다. 레코드를 테이블에 삭제하고 알림 (새로 삽입 된 레코드 ID만큼 간단 할 수 있음)을 동시에 대기열에 삭제하는 것이 좋습니다 . 테이블을 큐로 사용을 참조하십시오 .


1
카디널리티 사용자가 높은 다른 필터 열을 알지 못하므로 비트 열을 가장 왼쪽에 두는 데 아무런 이점이 없습니다. 지금까지 BIT 열이 클러스터형 인덱스의 마지막 선택임을 보았습니다. 그러나 "테이블을 대기열로 사용"에 대한 좋은 참고 자료를 보려면 +1입니다.
Anup Shah

2
실제로 테스트를 실행했으며 인덱스를 사용합니다. 테이블을 작성하고 (ID, myBit 비트) 비트가 0 인 비트를 100으로, 비트가 1 인 경우 2000000을 추가하십시오. 통계가 업데이트되고 (필요한 경우) myBit = 0에서 쿼리를 실행하면 인덱스가 사용됩니다.
케네스 피셔

@KennethFisher 인서트 TRUE / FALSE로 업데이트하는 일반적인 고속 패턴에서 통계는 항상 구식이됩니다. 당신이 명확한 디자인을하기보다는 옵티 마이저로 러시아어 룰렛을 좋아한다면, 당신은 당신이 원하는 것을 얻을 것입니다.
Remus Rusanu

"이제까지 그것을 사용하지 않습니다"그 진술은 사건의 99 %를 보유하고 있지만, 우리는 영업 이익에 어떤 경우 모르겠어요. 내가 성공적으로 비트에 색인을. 유스 케이스가 존재합니다.
usr

질문- 여기 에 답 맞지 않습니다. 특히> "비트 필드 (또는 일부 좁은 범위)를 인덱싱 할 때 해당 값과 일치하는 행 수만큼 작업 집합 만 줄입니다. 일치하는 행 수가 적은 경우 당신의 작업은 많은 설정 줄일 것 . 50/50 분포 많은 수의 행의 경우, 현재까지 인덱스를 유지 대 당신에게 약간의 성능 향상을 살 수 있습니다. " 어떤 경우에, 레코드의 1 %와 일치하는 비트의 인덱스는 상당한 증가를 위해 백만의 99 %를 스캔 할 필요가 없습니까?
drzaus

2

@MartinSmith가 말했듯이 SQL 2008로 업그레이드 한 경우 필터링 된 인덱스가 완벽한 솔루션이 될 것입니다. 그러나 일반적으로 ANY 추가 인덱스는 일반적으로로드 시간을 증가시킵니다. 작은 인덱스는 큰 인덱스보다 적습니다.

내가 볼 한 가지는 수정 가능한 기존 색인이 있는지입니다. 기존 쿼리가 주어진 인덱스를 사용한다고 가정하면 비트 열을 해당 인덱스의 끝에 추가하면 삽입에 미치는 영향이 최소화되고 쿼리에서 찾고있는 긍정적 인 효과가 발생합니다.

다음으로 볼 것은 "이미 많은 인덱스가 있습니까?"입니다. "많은"이 무엇인지에 대한 단단하고 빠른 규칙은 없지만, 난 보통 새로운 것을 필요로하지 않는 한 나는 보통 10 개의 색인 규칙을 따릅니다.

마지막으로 테스트 인스턴스에서 테스트하십시오. 수백만 개의 행이있는 테이블을 설정하고 테이블에로드를 실행하고 인덱스를 추가 한 후로드를 다시 실행하고로드 시간이 크게 증가하는지 확인하십시오.

오직 "유의 한"것이 무엇인지 결정할 수 있습니다. 로드 시간에 5 분을 추가하는 것이 "중요한"기계이고 몇 시간 동안 안전하게 볼 수있는 기계가 있습니다.

편집하다:

다른 옵션은 테이블을 분할하는 것입니다. Enterprise Edition을 사용하지 않지만 도움이된다면 분할 된 뷰를 사용해야 할 수도 있습니다. 한 파티션에는 비트 0을, 다른 파티션에는 비트 1을 넣습니다. 한 버전 만 삽입한다고 가정하면 삽입 속도를 높일 수도 있습니다.

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