SELECT… INTO 문 (PE003)을 사용해야하는 경우
SQL Server에서 SELECT…INTO
를 사용하여 테이블 원본에서 새 테이블을 만들 수 있습니다. SQL Server는 SELECT
목록에있는 식의 특성을 사용하여 새 테이블의 구조를 정의합니다.
SQL Server 2005 이전에는 SELECT…INTO
는 데이터베이스의 시스템 테이블에 대한 스키마 잠금을 획득하여 쿼리가 실행되는 동안 SQL Server가 응답하지 않는 것처럼 보이기 때문에 성능 ‘코드 냄새’였습니다. 이는 암시 적 트랜잭션의 DDL 문이기 때문에 데이터가 동일한 SQL 문 내에 삽입되어 필연적으로 오래 실행됩니다. 그러나이 동작은 잠금 모델이 변경된 SQL Server 2005에서 수정되었습니다.
SELECT…INTO
는 INSERT
INTO…SELECT…
. 이는 주로 SELECT…INTO
작업이 가능한 경우 대량 로그되기 때문입니다. 이제 INSERT
INTO
를 대량 로그 할 수 있지만 SQL Server 2012 및 2014에서 이러한 성능 이점을 볼 수 있습니다. = “0d5e266289″>
는 이러한 버전에서 병렬화 할 수 있지만 INSERT
INTO
의 병렬화 지원은 SQL Server에서만 나타납니다. 2016. 그러나 SELECT…INTO
를 사용하면 새 테이블에서 필요한 모든 인덱스 및 제약 조건 등을 정의하는 작업을 계속 수행 할 수 있습니다.
권장 사항 프로덕션 코드의 경우 SELECT…INTO
를 사용하지 마십시오. SQL 프롬프트 (PE003)에 코드 분석 규칙으로 포함되어 있습니다.
SELECT INTO 문을 사용하여 테이블 만들기
SQL Server의 SELECT…INTO
기능은 프로세스의 일부로 테이블 소스를 저장하거나 ‘지속’하도록 설계되었습니다. 다음은 간단한 예입니다.
그러나 테이블 소스는 사용자 정의 함수, OpenQuery
, OpenDataSource
, OPENXML
절, 파생 테이블, 조인 된 테이블, 피벗 된 테이블, 원격 데이터 소스, 테이블 변수 또는 가변 함수. 이러한 더 이국적인 테이블 소스를 사용하면 SELECT…INTO
구문이 더 유용 해집니다.
ANSI의 SELECT INTO 부분입니다. 표준?
ANSI 표준은 SELECT…INTO
구조를 지원합니다. 단일 선택이라고하며 값이있는 단일 행을로드하지만 거의 사용되지 않습니다 (이 점을 지적한 Joe Celko에게 감사드립니다).
사람들은 종종 SELECT…INTO
를 사용하여 테이블을 빠르게 복사하는 방법이라는 오해를 가지고 있습니다. 따라서에 정의 된 인덱스, 제약 조건, 계산 된 열 또는 트리거가 전혀 없다는 것은 놀랍습니다. 소스 테이블이 새 테이블로 전송됩니다. SELECT…INTO
문에도 지정할 수 없습니다. 또한 null 허용 여부 또는 계산 된 열 보존에 대해서는 아무 작업도 수행하지 않습니다. 이러한 모든 작업은 데이터를 제자리에두고 소급하여 수행해야하며, 이는 불가피하게 시간이 걸립니다.
하지만 IDENTITY
함수를 사용할 수 있습니다 (데이터 유형, 시드, 증분) ID 필드를 설정하고 소스가 단일 테이블 인 경우 대상 테이블의 열을 ID 열로 만들 수 있습니다. 개발자가 다른 열 속성을 전송할 것이라고 가정하게 만드는 것은 바로이 사실입니다.
또한 파티션을 나눈 테이블, 스파 스 열 또는 소스 테이블에서 상속 된 기타 속성을 만들 수 없습니다. 데이터가 많은 조인이 포함 된 쿼리 또는 일부 이국적인 외부 데이터 소스에서 오는 경우 어떻게 할 수 있습니까?
SQL 2012 SP1 CU10 이후로 SELECT…INTO
는 그러나 SQL Server 2016 이후로 기존의 INSERT INTO…SELECT
문에서 병렬 삽입이 허용되었으며 특정 제한 사항이 있으므로 … INTO
는 이제 다소 감소했습니다. INSERT
INTO
프로세스는 복구 모델을 설정하여 완전히 복구하는 대신 대량 로그 할 수있는 경우 속도를 높일 수도 있습니다. 단순 또는 대량 로깅, 빈 테이블 또는 힙에 삽입, 테이블에 대한 TABLOCK
힌트 설정
다음은 몇 가지 제한 사항을 요약 한 것입니다. SELECT…INTO
사용시 제한 사항.
- 열의
IDENTITY
속성이 전송되지만 다음과 같은 경우에는 전송되지 않습니다.-
SELECT
문에는 조인 된 테이블이 포함됩니다 (JOIN
또는UNION
),GROUP
BY
절 또는 집계 함수.IDENTITY
속성이 새 테이블로 전달되는 것을 방지해야하지만 열 값이 필요한 경우JOIN
를 절대 참이 아닌 조건 또는 행을 제공하지 않는UNION
에 대한 테이블 소스에 추가합니다. -
IDENTITY
열이SELECT
목록에 두 번 이상 나열됩니다. -
IDENTITY
열이 일부입니다. 표현식 -
IDENTITY
열은 원격 데이터 소스에서 가져옴
-
-
SELECT…INTO
테이블 반환 매개 변수 또는 테이블 변수를 대상으로 사용할 수 있지만FROM
선택할 수 있습니다. - 원본은 분할 된 테이블이고 새 테이블은 기본 파일 그룹에 생성됩니다. 그러나 SQL Server 2017에서는
ON
절을 통해 대상 테이블이 생성되는 파일 그룹을 지정할 수 있습니다. -
ORDER
BY
절이지만 일반적으로 무시됩니다. 이 때문에IDENTITY_INSERT
의 순서가 보장되지 않습니다. - 계산 된 열이
SELECT
목록에서 새 테이블의 해당 열은 계산 된 열이 아닙니다. 새 열의 값은SELECT…INTO
가 실행될 때 계산 된 값입니다. -
CREATE
TABLE
문,SELECT…INTO
문이 명시 적 트랜잭션에 포함 된 경우 영향을받는 시스템 테이블의 기본 행은 다음과 같습니다. 트랜잭션이 명시 적으로 커밋 될 때까지 배타적으로 잠 깁니다. 그 동안 이러한 시스템 테이블을 사용하는 다른 프로세스에서 차단이 발생합니다.
SELECT…INTO
임시 테이블을 사용합니다. SELECT…INTO
는 이에 대해 다소 불공평 한 평판을 얻었지만 과부하 상태에서 tempdb
의 래치 경합과 관련된보다 일반적인 문제의 일부였습니다. 작은 임시 테이블 생성 및 삭제. SELECT…INTO
가 열정적으로 채택되면 이러한 유형의 활동이 크게 늘어날 수 있습니다. 이 문제는 SQL Server 2016부터 더 이상 필요하지 않은 추적 플래그 TF1118을 사용하여 SQL Server 2000 이후부터 쉽게 수정할 수 있습니다. 자세한 설명은 TF 1118에 대한 오해를 참조하세요.
요약
요약하면 SELECT…INTO
는 테이블을 만드는 좋은 방법입니다. 제약 조건, 인덱스 또는 특수 열에 신경 쓰지 않는 경우 소스는 프로세스의 일부로 일시적으로 지속됩니다. 테이블 스키마의 가장 중요한 요소 만 복사 할 수 있으므로 테이블을 복사하는 좋은 방법이 아닙니다. 수년 동안 SELECT…INTO
의 매력을 증가 또는 감소시킨 요인이 있었지만 전반적으로 가능하면 사용을 피하는 것이 좋습니다. 대신 데이터의 일관성을 보장하도록 설계된 테이블이 보유한 모든 기능을 포함하는 테이블을 명시 적으로 만듭니다.