sql >> データベース >  >> RDS >> Sqlserver

テーブル変数にインデックスを作成する

    質問にはSQLServer2000のタグが付けられていますが、最新バージョンで開発している人々のために、最初に対処します。

    SQL Server 2014

    以下で説明する制約ベースのインデックスを追加する方法に加えて、SQL Server 2014では、テーブル変数宣言のインライン構文を使用して、一意でないインデックスを直接指定することもできます。

    そのための構文例を以下に示します。

    /*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 Server 2016 これをもう少しリラックスさせます。 CTP 3.1から、テーブル変数のフィルター処理されたインデックスを宣言できるようになりました。 RTMにより、可能性があります 含まれる列も許可されますが、現在の位置では、「リソースの制約のためにSQL16に組み込まれない可能性があります」

    /*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-2012

    名前にインデックスを作成できますか?

    簡単な答え:はい。

    DECLARE @TEMPTABLE TABLE (
      [ID]   [INT] NOT NULL PRIMARY KEY,
      [Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
      UNIQUE NONCLUSTERED ([Name], [ID]) 
      ) 
    

    より詳細な回答は以下のとおりです。

    SQL Serverの従来のテーブルは、クラスター化インデックスを持つことも、ヒープとして構造化することもできます。

    クラスタ化インデックスは、重複するキー値を許可しないように一意として宣言するか、デフォルトで非一意にすることができます。一意でない場合、SQL Serverは、重複するキーに一意化子をサイレントに追加して、それらを一意にします。

    非クラスター化インデックスは、一意として明示的に宣言することもできます。それ以外の場合、一意でない場合、SQL Serverは行ロケーター(クラスター化インデックスキーまたはヒープのRID)をすべてのインデックスキー(重複だけでなく)に追加します。これにより、それらが一意であることが保証されます。

    SQL Server 2000-2012では、テーブル変数のインデックスは、UNIQUEを作成することによってのみ暗黙的に作成できます。 またはPRIMARY KEY 制約。これらの制約タイプの違いは、主キーがnull許容でない列にある必要があることです。一意性制約に参加している列はNULL可能である可能性があります。 (ただし、NULLが存在する場合のSQLServerの一意の制約の実装 sは、SQL標準で指定されているものとは異なります)。また、テーブルは1つの主キーのみを持つことができますが、複数の一意の制約を持つことができます。

    これらの論理制約は両方とも、一意のインデックスを使用して物理的に実装されます。明示的に指定されていない場合、PRIMARY KEY はクラスター化されたインデックスになり、クラスター化されていない一意の制約になりますが、この動作はCLUSTEREDを指定することでオーバーライドできます。 またはNONCLUSTERED 制約宣言を使用して明示的に(構文例)

    DECLARE @T TABLE
    (
    A INT NULL UNIQUE CLUSTERED,
    B INT NOT NULL PRIMARY KEY NONCLUSTERED
    )
    

    上記の結果として、SQLServer2000-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                                 |
    +-------------------------------------+-------------------------------------+
    

    最後のものは少し説明が必要です。この回答の冒頭にあるテーブル変数の定義で、一意ではない Nameの非クラスター化インデックス ユニークによってシミュレートされます Name,Idのインデックス (SQL Serverは、クラスター化インデックスキーを一意でないNCIキーにサイレントに追加することを思い出してください)。

    IDENTITYを手動で追加することで、一意でないクラスター化インデックスを作成することもできます。 一意化子として機能する列。

    DECLARE @T TABLE
    (
    A INT NULL,
    B INT NULL,
    C INT NULL,
    Uniqueifier INT NOT NULL IDENTITY(1,1),
    UNIQUE CLUSTERED (A,Uniqueifier)
    )
    

    ただし、これは、すべての行に「一意化」を追加するため、非一意のクラスター化インデックスが実際にSQLServerに実際に実装される方法の正確なシミュレーションではありません。それを必要とする人だけではありません。



    1. 複合PRIMARYKEYは、関連する列にNOTNULL制約を適用します

    2. PostgreSQLは部分インデックスを使用しません

    3. RailsコンソールはIDの配列でユーザーを検索します

    4. DBaaS、クラウド、透過的なクエリルーティング