프로덕션 테이블에 열 추가


28

SQL Server 2008 R2에서 대규모 프로덕션 테이블에 열을 추가하는 가장 좋은 방법은 무엇입니까? Microsoft의 온라인 설명서에 따르면 :

ALTER TABLE에 지정된 변경 사항이 즉시 구현됩니다. 변경시 테이블의 행을 수정해야하는 경우 ALTER TABLE은 행을 업데이트합니다. ALTER TABLE은 테이블에서 스키마 수정 잠금을 획득하여 끝에서 매우 짧은 SCH-M 잠금이 필요한 온라인 인덱스 작업을 제외하고 다른 연결이 변경 중에 테이블의 메타 데이터를 참조하지 않도록합니다.

(http://msdn.microsoft.com/en-us/library/ms190273.aspx)

수백만 개의 행이있는 큰 테이블에서는 시간이 걸릴 수 있습니다. 정전이 유일한 옵션입니까? 이런 상황을 처리하는 가장 좋은 방법은 무엇입니까?


1
이 문제에 관한 최근 기사 : sqlservercentral.com/articles/Change+Tracking/74397
8kb

답변:


27

"의존한다"

행에 데이터를 추가 할 필요가없는 열을 추가하면 매우 빠릅니다.

예를 들어, int 또는 char을 추가하려면 실제 행 이동이 필요합니다. NULL 비트 맵을 확장해야하는 경우를 제외하고 기본값없이 널 입력 가능 varchar를 추가하면 안됩니다.

견적을 받으려면 복원 된 프로덕션 사본에서 시도해야합니다.

10 억 행 테이블에 인덱스와 키를 다시 추가해야하는 경우 새 테이블을 만들고 복사하고 이름을 바꾸면 시간이 더 오래 걸릴 수 있습니다.

nullable 열을 추가하는 데 몇 초가 걸리는 10 억 행 테이블을 변경했습니다.

백업을 먼저하라고 했습니까?


2
백업에서 +1 충분한 로그 공간이 있는지 확인하십시오.
SqlACID

int 또는 char을 추가하면 실제 행 이동이 필요한 이유를 알 수 있습니까?
sh-beta

5
"두 번째 줄의 행에 데이터를 추가하지 않아도된다"는 말입니까?
Ben Brocka

21

열이 NULL 인 경우 영향은 무시해도됩니다. 열이 NULL 일 수없고 값을 설정해야하는 경우에는 상당히 다를 수 있습니다. 이 경우 내가 할 일은 null이 아닌 기본 제약 조건을 한 번에 추가하는 대신 모든 행에 효과적으로 데이터를 추가하는 것입니다.

  • 열을 NULLable로 추가-대부분의 경우 빠릅니다.
  • 값을 기본값으로 업데이트
    • 필요한 경우 일괄 처리 로이 작업을 수행 할 수 있습니다
    • 이것을 사용하여 일부 행이 기본값을 얻지 못하는 조건부 논리를 적용 할 수 있습니다
  • not null / 기본 제약 조건 추가
    • 데이터가 NULL이 아닌 경우 더 빠르지 만 여전히 측정 가능해야합니다.

@gbn에 동의하면 프로덕션 복사본을 복원하고 시도하여 테스트 할 수 있습니다 ... 하드웨어가 다소 비슷하다고 가정하면 트랜잭션 로그에 미치는 영향을 볼 수 있습니다.


마지막 비트 다시 : •add the not null/default constraints이것에 잠재적 인 문제가 있는지 확실하지 않습니다 ... MSSQL (2008R2조차도)이 null이 아닌 열을 null로 변경하면 추적을하면 실제로 커버 아래에서 볼 수 있습니다 테이블의 모든 행을 완전히 업데이트합니다. 즉 update table1 set column1 = column1, 완전히 바보 같은 방식으로 null이 아닌 확인을 수행한다고 가정합니다. 이 트랜잭션은 테이블 크기의 두 배 (페이지 전후)이므로 DW 테이블의 경우 크기가 클 수 있습니다. 이전에는 데이터를 bcp 아웃하고, 잘라 내고, null에서 non-null로 변경 한 다음 bcp를 입력해야했습니다.

누구 든지이 문제를 해결할 방법을 알고 있다면 알고 싶습니다 ... 대조적으로 Oracle에서 null을 null로 변경하지 않으면 잠금이 발생하고 null이 아닌 것을 확인하는 선택은 순전히 메타 데이터 업데이트입니다.

@Mike, 이것은 그 자체로 좋은 잠재적 질문처럼 들립니다.
데릭 다우니

4

다음을 고려 했습니까?

  1. 테이블 정의에 대한 변경 사항이 포함 된 새 테이블 작성
  2. 원래 테이블에서 선택하여 새 테이블 정의에 삽입합니다.
  3. 원래 테이블의 이름을 _orig로 바꾼 다음 새 테이블의 이름을 원래 테이블 이름으로 바꿉니다.

여기서 단점은이 변경을 수행하기 위해 데이터베이스에 충분한 공간이 있어야한다는 것입니다. 더티 읽기를 방지하기 위해 여전히 테이블에 대한 읽기 잠금이 필요할 수 있습니다.

그러나 원본 테이블에 동시에 액세스 할 가능성이 있거나 필요한 경우 최종 사용자에게 미치는 영향을 최소화합니다. 또한 잠금 기간을 최소화해야합니다.


읽기보다는 쓰기 잠금 이 필요하지 않습니까? 사용자가 이전 테이블의 데이터를 보는 것이 좋습니다. 버퍼 스왑을 마칠 때 덮어 쓰는 변경 사항을 커밋하지 않기를 바랍니다.
모든 거래의 존

변경 사항을 좀 더 쉽게 제어 할 수있는 데이터웨어 하우스 모자에 대한 생각이었습니다. OLTP 상황에서는 테이블이 변경되지 않도록 쓰기 잠금이 필요합니다.
RobPaller
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.