2010-07-28 5 views
0

많은 열을 비교해야하는 병합 문이 있습니다. 원본 테이블에는 26,000 개의 행이 있습니다. 대상 테이블에는 수백만 개의 행이 있습니다. Desintation 테이블은 int 유형 컬럼에 대한 일] 기본 키 인덱스 만 갖습니다.SQL Server 병합 및 인덱싱 속도

소스에서 고유 값의 수를 계산하려면 group by를 사용하여 일부 선택을했습니다.

병합의 테스트 부분은

Merge Into desttable 
Using #temptable 
On 
(
desttable.ColumnA = #temptable.ColumnA 
and 
desttable.ColumnB = #temptable.ColumnB 
and 
desttable.ColumnC = #temptable.ColumnC 
and 
desttable.ColumnD = #temptable.ColumnD 
and 
desttable.ColumnE = #temptable.ColumnE 
and 
desttable.ColumnF = #temptable.ColumnF 
) 
When Not Matched Then Insert Values (.......) 

-- ColumnA: 167 unique values in #temptable 
-- ColumnB: 1 unique values in #temptable 
-- ColumnC: 13 unique values in #temptable 
-- ColumnD: 89 unique values in #temptable 
-- ColumnE: 550 unique values in #temptable 
-- ColumnF: 487 unique values in #temptable 

-- ColumnA: 3690 unique values in desttable 
-- ColumnB: 3 unique values (plus null is possible) in desttable 
-- ColumnC: 1113 unique values in desttable 
-- ColumnD: 2662 unique values in desttable 
-- ColumnE: 1770 unique values in desttable 
-- ColumnF: 1480 unique values in desttable 

병합 지금 매우, 매우 오랜 시간이 걸립니다. 내 기본 키를 변경해야하지만 가장 좋은 전략이 무엇인지 모릅니다. 첫 번째 병합에는 26,000 개의 행을 삽입 할 수 있지만 후속 병합에는 ~ 2,000 개의 삽입 만 수행 할 수 있습니다. 색인이없고 단순한 PK 만 있기 때문에 모든 것이 느립니다. :)

더 나은 방법을 알려줄 수 있습니까?

감사합니다.

+0

현재 병합이 어떻게 작동하는지 알아야합니다. 현재 열거 한 6 개 열의 평등을 확인합니까? 대체 키입니까? 그렇다면 이러한 열에 대해 고유 한 복합 색인이 있습니까? 이 열은 어떤 데이터 유형입니까? 큰 경우 체크섬 추가를 고려 했습니까? –

+0

스키마 및 인덱스를 추가하고 쿼리 할 수 ​​있습니까? 더 많은 열에 인덱스가 필요하지만 더 많은 정보가 필요합니다 ... – gbn

+1

역겨운 표현은 강한 의미입니다. 나는 게으르다. 게으름이 고쳤다. 미안, 아베. – Snowy

답변

2

글쎄, 확실한 후보자는 MERGE 성명서에서 일치하는 데 사용하는 열의 색인 일 것입니다. 귀하의 대상 테이블에 (ColumnA, ColumnB, ColumnC, ColumnD, ColumnE, ColumnF)의 색인이 있습니까?

이 튜플 열은 원본 테이블의 행이 데이터베이스에 이미 있는지 여부를 확인하는 데 사용됩니다. 해당 색인이나 다른 사용 가능한 색인이 없으면 기본적으로 원본 테이블의 각 행에 대해 큰 대상 테이블에서 테이블 스캔을받습니다.

그렇지 않은 경우 : 추가하고 런타임 동작이 어떻게 변경되는지 확인하려고합니다. MERGE이 이제는 매우 오랜 시간보다 조금 더 오래 실행됩니까 ??

+0

조금 더 실험하면서 destructable varchar (42) 'HashCol'에서 고유 한 인덱스를 만든 다음 temp 테이블에 col을 다음과 같이 추가했습니다. 업데이트 #temptable Set HashCol = (SUBSTRING (master.dbo.fn_varbintohexstr을 (SELECT HASHBYTES ('SHA1을' 캐스트 ([COLUMNA 바와 같이 VARCHAR (16)) + COLUMNB ColumnC + + + ColumnD ColumnE ColumnF +)) (3) 32)) 그런 다음 proc에서 HashCol에 대한 색인을 생성 한 다음이를 병합합니다. 나는 최적의 순서가 칼럼에 어떤 것인지를 잘 모르기 때문에 복합 인덱스를 만들려고하지 않았다. IIRC는 가장 고유 한 칼럼을 가장 먼저 사용해야한다. – Snowy

+0

나는 HashCol을 추가하기로 결정했습니다. 왜냐하면 ColumnB가 null 일 수있는 오류 사례를 발견했기 때문에 스크립트에서 쉽게 볼 수있는 오류가 발생했습니다. 또한 컬럼이 변경 될 수 있음을 알았고 복합 인덱스를 삭제하고 다시 작성하는 것보다 HashCol에서 '중요한 것'을 변경하는 것이 더 쉽습니다. 제안 해 주셔서 감사합니다. – Snowy

1

시간을 중요하게 생각하지 않는다면 병합 문을 사용할 수 있다면 한 번만 실행하면됩니다. 그러나 스크립트를 더 자주 사용하려는 경우 병합 문을 사용하는 대신 단계별로 수행하는 것이 더 좋을 것이라고 생각합니다. 목표를 달성하기 위해 자신의 select, insert, update, delete 문을 작성하는 것과 같은 단계별로 단계별로 수행하십시오. 이것으로 당신은 거의 모든 것을 제어 할 수 있습니다. (쿼리 최적화, 인덱싱 등 ...)

당신의 경우에는 6 개의 기준을 모두 분리하는 것이 더 효과적 일 수 있습니다. 단점은 더 이상 스크립트가 필요합니다.

+0

왜 자신을 굴리세요 ?? 나는 당신이 머지 진술보다 더 빠르게 관리 할 수 ​​있을지는 의심 스럽다 ...... 더하기 : 머저 진술은 하나의 트랜잭션 단위이다. - 스스로 롤을 돌리면, 기본적인 부기와 관리를 많이해야한다. .. –

+0

정확하게, 거대한 데이터 세트를 가진 하나의 트랜잭션 유닛을 작은 데이터 세트를 가진 다중 트랜잭션 유닛으로 분해하는 것이 더 빠를 것입니다. 은 26,000 또는 100 만 개의 행을 처리하려는 경우 그의 샘플을 좋아합니다. SET_A = Table1.ColA = Table2.ColA SET_B = SET_A = Table2.ColB ... Table1.ColB 1보다 큰 일련의 모든 기준 : 은 세트 당 1 개 기준이 더 나은 것 결과 = 여기서 Table1.ColA = Table2.ColA 및 Table1.ColB = Table2.ColB 및 ... 이 시점에서 인덱싱에 관계없이. 관리와 관련하여 부기? 그것은 단지 하나의 스크립트 일 뿐이며, 나는 그 어떤 문제도 보지 못합니다. –

+0

그 6 개의 열은 합류 기준입니다 - 어떻게 분할 할 수 있는지 제안 할 수 없습니다. –

관련 문제