프로덕션 테이블에 열 추가


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.