SQL Server를 사용하여 CREATE TABLE 문 내에서 클러스터되지 않은 고유하지 않은 인덱스 만들기


95

SQL Server CREATE TABLE 문 내에서 기본 키 또는 고유 인덱스를 만들 수 있습니다. CREATE TABLE 문 내에서 고유하지 않은 인덱스 를 만들 수 있습니까?

CREATE TABLE MyTable(
    a int NOT NULL
    ,b smallint NOT NULL
    ,c smallint NOT NULL
    ,d smallint NOT NULL
    ,e smallint NOT NULL

    -- This creates a primary key
    ,CONSTRAINT PK_MyTable PRIMARY KEY CLUSTERED (a)

    -- This creates a unique nonclustered index on columns b and c
    ,CONSTRAINT IX_MyTable1 UNIQUE (b, c)

    -- Is it possible to create a non-unique index on columns d and e here?
    -- Note: these variations would not work if attempted:
    -- ,CONSTRAINT IX_MyTable2 INDEX (d, e)
    -- ,CONSTRAINT IX_MyTable3 NONCLUSTERED INDEX (d, e)
);
GO

-- The proposed non-unique index should behave identically to
-- an index created after the CREATE TABLE statement. Example:
CREATE NONCLUSTERED INDEX IX_MyTable4 ON MY_TABLE (d, e);
GO

다시 말하지만, 목표는 CREATE TABLE 문 뒤가 아니라 내에서 고유하지 않은 인덱스를 만드는 것입니다.

그만한 가치가있는 [CREATE TABLE에 대한 SQL Server 온라인 설명서 항목]을 찾지 못했습니다 . 이 도움 .

또한 [This Question] 은 거의 동일하지만 수락 된 답변은 적용되지 않습니다.

답변:


126

당신은 할 수 없습니다. CREATE / ALTER TABLE은 인덱스가 아닌 CONSTRAINT 만 추가 할 수 있습니다. 기본 키와 고유 제약 조건이 인덱스 측면에서 구현된다는 사실은 부작용입니다. 인덱스를 관리하려면 잘 알고 있듯이 CREATE / ALTER / DROP INDEX가 있습니다.

CREATE TABLE 문에 비 고유 비 클러스터형 인덱스를 추가해야하는 이유는 무엇입니까?

SQL Server 2014에는 인라인 인덱스 생성 옵션이 도입되었습니다 .

CREATE TABLE MyTable(
    a int NOT NULL
    ,b smallint NOT NULL
    ,c smallint NOT NULL
    ,d smallint NOT NULL
    ,e smallint NOT NULL

    -- This creates a primary key
    ,CONSTRAINT PK_MyTable PRIMARY KEY CLUSTERED (a)

    -- This creates a unique nonclustered index on columns b and c
    ,CONSTRAINT IX_MyTable1 UNIQUE (b, c)

    -- This creates a non-clustered index on (d, e)
    ,INDEX IX_MyTable4 NONCLUSTERED (d, e)
);
GO

17
훌륭한 설명에 감사드립니다! 왜? 순전히 미적 이유로. 모든 제약 조건 / 인덱스가 동일한 문에 포함되어 있으면 스크립트를 읽는 사람에게 편리 할 수 ​​있다고 생각했습니다. 개인적으로, 외래 키에 속한 열에도 인덱스가 있는지 알고 싶습니다. 이것은 동일한 명령문에서이 정보를 논리적으로 그룹화하는 좋은 방법 일 수 있습니다.
Mike

나는 Error: (1146) Table 'tablename' doesn't exist,
hahahah

13

에 따라 T-SQL은 표 CREATE 2014 년, 인덱스를 정의 열 정의에서 지원하는 문서를 :

<column_definition> ::=  
column_name <data_type>  
    ...
    [ <column_index> ]  

문법은 다음과 같이 정의됩니다.

<column_index> ::=   
 INDEX index_name [ CLUSTERED | NONCLUSTERED ]  
    [ WITH ( <index_option> [ ,... n ] ) ]  
    [ ON { partition_scheme_name (column_name )   
         | filegroup_name  
         | default   
         }  
    ]   
    [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]  

따라서 별도의 문으로 수행 할 수있는 많은 작업을 인라인으로 수행 할 수 있습니다. 나는 include이 문법에서 옵션이 아니기 때문에 어떤 것은 불가능하다는 것을 알았습니다 .

CREATE TABLE MyTable(
    a int NOT NULL
    ,b smallint NOT NULL index IX_MyTable_b nonclustered
    ,c smallint NOT NULL
    ,d smallint NOT NULL
    ,e smallint NOT NULL
)

또한 열 뒤에 다른 줄로 정의 된 인라인 인덱스를 가질 수 있지만 create table 문 내에서 인덱스에 여러 열을 허용하지만 여전히 include절 은 없습니다 .

< table_index > ::=   
{  
    {  
      INDEX index_name [ CLUSTERED | NONCLUSTERED ]   
         (column_name [ ASC | DESC ] [ ,... n ] )   
    | INDEX index_name CLUSTERED COLUMNSTORE  
    | INDEX index_name [ NONCLUSTERED ] COLUMNSTORE (column_name [ ,... n ] )  
    }  
    [ WITH ( <index_option> [ ,... n ] ) ]   
    [ ON { partition_scheme_name (column_name )   
         | filegroup_name  
         | default   
         }  
    ]   
    [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]  

}   

예를 들어 여기에서는 c와 d 열에 인덱스를 추가합니다.

CREATE TABLE MyTable(
    a int NOT NULL
    ,b smallint NOT NULL index IX_MyTable_b nonclustered
    ,c smallint NOT NULL
    ,d smallint NOT NULL
    ,e smallint NOT NULL

    ,index IX_MyTable_c_d nonclustered (c,d)
)

1
이것은 훌륭하게 작동하며 BOL에 따르면 적어도 2008 년으로 거슬러 올라갑니다. OP와 마찬가지로 대부분의 코드 (보통 SSMS에 의해 생성됨)가 내 눈을 아프게하고 합리적 인간에게 의미가있는 테이블 정의를 좋아합니다. 감사.
Wade Hatler

8

별도의 진술입니다.

또한 테이블에 삽입하고 테이블에서 선택하고 동일한 명령문에서 인덱스를 작성하는 것도 불가능합니다.

BOL 항목에는 필요한 정보가 포함되어 있습니다.

클러스터링 됨 | NONCLUSTERED
PRIMARY KEY 또는 UNIQUE 제약 조건에 대해 클러스터형 또는 비 클러스터형 인덱스가 생성 되었음을 나타냅니다. PRIMARY KEY 제약 조건은 기본적으로 CLUSTERED로, UNIQUE 제약 조건은 기본적으로 NONCLUSTERED로 설정됩니다.

CREATE TABLE 문에서 CLUSTERED는 하나의 제약 조건에만 지정할 수 있습니다. UNIQUE 제약 조건에 대해 CLUSTERED가 지정되고 PRIMARY KEY 제약 조건도 지정되면 PRIMARY KEY의 기본값은 NONCLUSTERED입니다.

PK 필드에 인덱스를 만들 수 있지만 pk가 아닌 비 고유 제약 필드의 클러스터되지 않은 인덱스는 만들 수 없습니다.

NCL 인덱스는 테이블 구조와 관련이 없으며 테이블 내부 데이터에 대한 제약 조건이 아닙니다. 테이블을 지원하지만 기능이나 디자인에 필수적인 것은 아닌 별도의 엔터티입니다.

그것이 별도의 진술인 이유입니다. NCL 인덱스는 디자인 관점에서 테이블과 관련이 없습니다 (쿼리 최적화에도 불구하고).


7

인덱스 인라인 테이블 생성 스크립트 를 만드는 방법에 대한 대답이 저에게 효과적이지 않았습니다. 이것은 :

CREATE TABLE [dbo].[TableToBeCreated]
(
    [Id] BIGINT IDENTITY(1, 1) NOT NULL PRIMARY KEY
    ,[ForeignKeyId] BIGINT NOT NULL
    ,CONSTRAINT [FK_TableToBeCreated_ForeignKeyId_OtherTable_Id] FOREIGN KEY ([ForeignKeyId]) REFERENCES [dbo].[OtherTable]([Id])
    ,INDEX [IX_TableToBeCreated_ForeignKeyId] NONCLUSTERED ([ForeignKeyId])
)

외래 키는 인덱스를 생성하지 않으므로 조인 할 가능성이 높으므로 인덱스를 인덱싱하는 것이 좋습니다.


나는 그 마지막 진술을 따르지 않습니다. 외래 키로 테이블을 쿼리하는 것이 일반적인 관행이라면 그 진술에 동의합니다. 그러나 단순히 그것에 가입하는 것이 아니므로 색인화되어야합니다. 예 : 모든 직원과 회사 ID X의 회사 이름을 찾은 다음 FK의 색인이 도움이되는지 확인하십시오. 성이 A로 시작하는 모든 직원과 회사 이름을 찾습니다. FK의 색인은 도움이되지 않습니다. 즉, "당신이 그것에 가입하기 때문에 당신은 그것을 색인해야한다"가 좋은 실행인지 확신하지 못한다. 내가 뭔가를 놓치고 있습니까?
Paul

2
인덱스는 조인 쿼리를 더 빠르게 만듭니다.
ScubaSteve
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.