SQL Server 2000에서 테이블 변수에 인덱스를 만들 수 있습니까?테이블 변수에 인덱스 만들기
는
DECLARE @TEMPTABLE TABLE (
[ID] [int] NOT NULL PRIMARY KEY
,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL
)
나는 이름에 인덱스를 만들 수 즉?
SQL Server 2000에서 테이블 변수에 인덱스를 만들 수 있습니까?테이블 변수에 인덱스 만들기
는
DECLARE @TEMPTABLE TABLE (
[ID] [int] NOT NULL PRIMARY KEY
,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL
)
나는 이름에 인덱스를 만들 수 즉?
질문에 SQL Server 2000 태그가 지정되었지만 최신 버전으로 개발하는 사람들을 위해 먼저 해결할 것입니다.
는SQL 서버 2014 후술 제약 기반 인덱스를 추가하는 방법 외에 2,014
SQL 서버는 비 고유 인덱스 테이블 변수 선언 인라인 구문을 직접 지정할 수있다.
구문의 예는 다음과 같습니다. 포함 된 열
/*SQL Server 2014+ compatible inline index syntax*/
DECLARE @T TABLE (
C1 INT INDEX IX1 CLUSTERED, /*Single column indexes can be declared next to the column*/
C2 INT INDEX IX2 NONCLUSTERED,
INDEX IX3 NONCLUSTERED(C1,C2) /*Example composite index*/
);
필터링 된 인덱스와 인덱스가 현재이 구문 그러나 SQL 서버 2016로 선언 할 수없는 것은 조금 더이 이완한다. CTP 3.1부터 테이블 변수에 대해 필터링 된 인덱스를 선언 할 수 있습니다.
2012 난을 만들 수 - RTM으로는 컬럼도 허용되지만 현재 위치가 그들이 "will likely not make it into SQL16 due to resource constraints"
/*SQL Server 2016 allows filtered indexes*/ DECLARE @T TABLE ( c1 INT NULL INDEX ix UNIQUE WHERE c1 IS NOT NULL /*Unique ignoring nulls*/ )
SQL Server 2000에 있다는 것입니다 포함 된 경우 일 수 이름에 대한 색인?
짧은 대답 : 예.
DECLARE @TEMPTABLE TABLE (
[ID] [INT] NOT NULL PRIMARY KEY,
[Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
UNIQUE NONCLUSTERED ([Name], [ID])
)
자세한 대답은 아래에 있습니다.
SQL Server의 기존 테이블은 클러스터 된 인덱스를 갖거나 heaps으로 구조화 될 수 있습니다.
클러스터 된 인덱스는 중복 키 값을 허용하지 않으려면 고유 한 것으로 선언하거나 비 고유로 기본값을 선언 할 수 있습니다. 고유하지 않으면 SQL Server는 중복 키에 자동으로 uniqueifier을 추가하여 고유하게 만듭니다.
클러스터되지 않은 인덱스도 고유하게 명시 적으로 선언 할 수 있습니다. 그렇지 않으면 고유하지 않은 모든 SQL Server adds the row locator (클러스터 된 인덱스 키 또는 힙의 경우 RID)을 모든 인덱스 키 (중복이 아님)에 다시 지정하면 고유 한 값이됩니다.
SQL Server 2000 - 2012에서 테이블 변수의 인덱스는 UNIQUE
또는 PRIMARY KEY
제약 조건을 만들어 암시 적으로 만 만들 수 있습니다. 이러한 제약 조건 유형의 차이점은 기본 키가 null이 아닌 열 (들)에 있어야한다는 것입니다. 고유 제한 조건에 참여하는 컬럼은 널 (NULL) 입력 가능할 수 있습니다. (NULL
이있는 상태에서 SQL Server의 고유 제약 조건 구현은 SQL 표준에 지정된 제약 조건이 아님). 또한 테이블에는 기본 키가 하나만있을 수 있지만 고유 한 제약 조건이 여러 개 있습니다.
이러한 논리 제약 조건은 물리적으로 고유 한 인덱스로 구현됩니다. 명시 적으로 지정되지 않은 경우 PRIMARY KEY
는 클러스터 된 인덱스가 될 것이며, 고유 제한 조건은 클러스터되지 않은 그러나이 동작은 위의 결과로 제약 선언으로 명시 적으로 (예 구문)
DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)
을 CLUSTERED
또는 NONCLUSTERED
를 지정하여 대체 할 수 있습니다 2012 년
+-------------------------------------+-------------------------------------+
| Index Type | Can be created on a table variable? |
+-------------------------------------+-------------------------------------+
| Unique Clustered Index | Yes |
| Nonunique Clustered Index | |
| Unique NCI on a heap | Yes |
| Non Unique NCI on a heap | |
| Unique NCI on a clustered index | Yes |
| Non Unique NCI on a clustered index | Yes |
+-------------------------------------+-------------------------------------+
마지막 약간의 설명이 필요 - 다음 인덱스는 암시 2000은 SQL Server의 테이블 변수를 만들 수 있습니다. 이것의 시작 부분에 테이블 변수 정의에서 Name,Id
에 독특한 인덱스 시뮬레이션 Name
에 비 독특한 비 클러스터형 인덱스 대답 (자동 어쨌든 비 독특한 NCI 키에 클러스터 된 인덱스 키를 추가하는 SQL 서버를 리콜).
고유하지 않은 클러스터 된 인덱스는 IDENTITY
열을 수동으로 추가하여 고유 식별자 역할을 수행 할 수도 있습니다.
DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)
는하지만이 모든 행에 "uniqueifier를"을 추가로 비 고유 클러스터형 인덱스는 일반적으로 실제로 SQL 서버에서 구현 될 것입니다 방법에 대한 정확한 시뮬레이션이 아니다. 뿐만 아니라 그것을 필요로하는 사람들.
참고 : 2000-2012 솔루션은 텍스트 열 <= 900 바이트 인 경우에만 작동합니다. 즉. varchar (900), nvarchar (450) –
@AndreFigueiredo 예, 해당 버전의 영구 테이블에도 인덱스 키의 최대 크기입니다. –
저는 SQL 2014 대답이 Azure에서 잘 작동한다는 것을 알고 싶었습니다. Martin 고마워! – Jaxidian
성능 측면에서 변수를 선호하는 @temp 테이블과 #temp 테이블간에 차이가 없음을 이해해야합니다. 이들은 같은 장소 (tempdb)에 상주하며 동일한 방식으로 구현됩니다. 모든 차이점이 추가 기능에 나타납니다. https://dba.stackexchange.com/questions/16385/whats-the-difference-between-a-temp-table-and-table-variable-in-sql-server/16386#16386
테이블 또는 스칼라 함수와 같이 임시 테이블을 사용할 수없는 경우가 있지만 v2016 이전의 대부분의 경우 (필터링 된 인덱스조차도 테이블에 추가 할 수있는 경우도 있음) 변수)를 사용하면 간단히 #temp 테이블을 사용할 수 있습니다.
tempdb에서 명명 된 인덱스 (또는 제약 조건)를 사용하면 단점은 이름이 충돌 할 수 있다는 것입니다. 이론적으로는 다른 프로 시저를 사용하는 것뿐만 아니라 #temp 테이블의 복사본에 동일한 인덱스를 넣으려고하는 다른 프로 시저 인스턴스를 사용하는 경우도 있습니다.
이름 충돌을 방지하기 위해이 같은 일반적으로 작동합니다declare @cmd varchar(500)='CREATE NONCLUSTERED INDEX [ix_temp'+cast(newid() as varchar(40))+'] ON #temp (NonUniqueIndexNeeded);';
exec (@cmd);
이 이름도 동일한 절차의 동시 실행 사이에 항상 고유 보장한다.
varchar (40) 다음에 괄호가 하나씩없는 경우 추가하십시오. –
명명 된 인덱스에는 문제가 없습니다. 인덱스는 테이블 내에서 고유하게 이름 지정되어야합니다. 문제는 명명 된 제약 조건에 있으며 최적의 솔루션은 일반적으로 임시 테이블에서 이름을 지정하지 않는 것입니다. 명명 된 제약 조건은 임시 테이블 개체 캐싱을 방지합니다. –
특정 버전에만 해당해야합니다 (모든 버전에 해당되는 경우). 동시 실행 중에 이름이 지정된 인덱스의 충돌에 sp 실패를 추적 했으므로 특히이 해결 방법을 찾아야했습니다. – bielawski
두 종류의 임시 테이블을 만드는 데 비용이 소요됩니다. 그리고 인덱스가 필요하다는 데이터가 너무 많으면 실제 테이블을 사용할 때가 있습니다. 거래 안전을 위해 설정 한 spid 또는 사용자 ID별로 필터링 한 다음 끝에 끝내십시오. 실수 테이블 v 임시 테이블은 성능이 문제가되는 경우에는 둘 다 기복이 있습니다. 진짜 테이블도 함께 시도해보십시오. – u07ch
임시 테이블 'IS'는 실제 테이블이며 완료되면 사라집니다. 실제 차이점은 (자동으로 사라지는 것 외에는) TempDB에 있다는 것입니다. 인덱스와 제약 조건에 대해서는 실제로 엄청나 다. 왜냐하면 코드의 다른 실행뿐만 아니라 인스턴스의 다른 데이터베이스에서 코드가 실행되는 이름 충돌로 끝날 수 있기 때문입니다. – bielawski
@bielawski 이것은 임시 테이블이 아닌 테이블 변수입니다. 테이블 변수는 명시 적으로 명명 된 제약 조건을 허용하지 않으므로 시스템 생성 이름은 고유해야합니다.그들은 2014 년부터 명명 된 인덱스를 허용합니다. 그러나 인덱스는 오브젝트 전체가 아닌 오브젝트 내에서 유일하게 명명되어야하기 때문에 문제가되지 않습니다. –