Oracle USING INDEX句に相当するSQL Server


9

OracleのUSING INDEX句に相当するSQL Server 2008はありますか?具体的には、構成:

CREATE TABLE c(c1 INT, c2 INT);
CREATE INDEX ci ON c (c1, c2);
ALTER TABLE c ADD CONSTRAINT cpk PRIMARY KEY (c1) USING INDEX ci;

Sql Server Documentation on Unique Indexsには、次のように記載されています(強調を追加)。

一意のインデックスは、次の方法で実装されます。

PRIMARY KEYまたはUNIQUE制約

PRIMARY KEY制約を作成すると、テーブルにクラスター化インデックスがまだ存在せず、一意の非クラスター化インデックスを指定しない場合、列に一意のクラスター化インデックスが自動的に作成されます。主キー列はNULL値を許可できません。

これは、主キーに使用するインデックスを指定する方法があることを意味しているようです。


PKをテーブルと一緒に定義するだけです。create table c (c1 int not null primary key, c2 int)
a_horse_with_no_name

それは私がに興味があることを一部「PKは、名前のインデックスを使用すること」だ。
NIK

いいえ、それを行う方法はありません。主キーは制約とインデックスです。あなたが提供したものでは、主キーはデフォルトで一意のクラスター化インデックスになります。where句にc1とc2の両方を含めない限り、他の定義済みインデックスが重複します。
アーロン

回答:


7

OracleのUSING INDEX句に相当するSQL Server 2008はありますか?

いいえ。SQLServerで主キーまたは一意制約を作成すると、その制約をサポートする一意のインデックスが同じキーで自動的に作成されます。

これは、主キーに使用するインデックスを指定する方法があることを意味しているようです。

いいえ。ドキュメントは、指定しない場合、自動サポートインデックスがクラスター化されたものとして作成されるか、非クラスター化されたものとして作成されるかを説明することのみを目的としています。紛らわしい言葉遣いだと思います。

あなたは好みを表現することなく、既存のテーブルに主キー制約を追加するときに、明確にするために、サポートしている索引がされ、クラスタ化表には、既存のクラスタ化インデックスが存在しない場合。クラスター化インデックスが既に存在する場合、サポートインデックスは非クラスター化として作成されます

あなたは、特に使用してクラスタ化または非クラスタ化主キーを要求することができますPRIMARY KEY CLUSTEREDPRIMARY KEY NONCLUSTERED

公平に言えば、この文書は次の点でより明確です。

table_constraint(Transact-SQL)


5

主キーでもあるクラスター化インデックスを作成するためのSQL Server構文は次のとおりです。

CREATE TABLE dbo.c
(
    c1 INT NOT NULL, 
    c2 INT NOT NULL,
    CONSTRAINT PK_c
    PRIMARY KEY CLUSTERED (c1, c2)
);

「PKに名前付きインデックスを使用させる」というコメントの範囲では、上記のコードは「PK_c」という名前の主キーインデックスになります。

主キーとクラスタリングキーは同じ列である必要はありません。個別に定義できます。上記の例では、CLUSTEREDキーワードをに変更NONCLUSTEREDし、CREATE INDEX構文を使用してクラスター化インデックスを追加します。

CREATE TABLE dbo.c
(
    c1 INT,
    c2 INT,
    CONSTRAINT PK_c
    PRIMARY KEY NONCLUSTERED (c1, c2)
);

CREATE CLUSTERED INDEX CX_c ON dbo.c (c2);

SQL Serverでは、クラスター化インデックステーブルであり、まったく同じです。クラスタ化インデックスは、テーブルに格納されている行の論理的な順序を定義します。最初の例では、行はc1c2列の値の順に格納されています。クラスタリングキーは主キーとしても定義されているため、との組み合わせはテーブル全体で一意c1であるc2必要があります。

2番目の例では、主キーはc1c2列で構成されていますが、クラスタリングキーは単なるc2列です。ステートメントでUNIQUE属性を指定しなかったためCREATE INDEX、クラスタリングキー(c2)はテーブル全体で一意である必要はありません。「一意化」はSQL Serverによって自動的に作成されc2、クラスタリングキーを作成するために列の値に追加されます。このクラスタリングキーは一意になったため、テーブルに作成された他のインデックスの行IDとして使用されます。

クラスタリングキーがストレージ内の行のレイアウトを制御することを証明するために、文書化されていない関数を使用できますfn_PhysLocCracker(%%PHYSLOC%%)。次のコードはc2、クラスタ化キーとして定義した列の順序で行がディスクに配置されることを示しています。

USE tempdb;

CREATE TABLE dbo.PKTest
(
    c1 INT NOT NULL
    , c2 INT NOT NULL
    , c3 VARCHAR(256) NOT NULL
);

ALTER TABLE PKTest 
ADD CONSTRAINT PK_PKTest 
PRIMARY KEY NONCLUSTERED (c1, c2);

CREATE CLUSTERED INDEX CX_PKTest 
ON dbo.PKTest(c2);

TRUNCATE TABLE dbo.PKTest;

INSERT INTO dbo.PKTest (c1, c2, c3)
SELECT TOP(25) o1.object_id / o2.object_id, o2.object_id, o1.name + '.' + o2.name
FROM sys.objects o1
    , sys.objects o2
WHERE o1.object_id >0 
    and o2.object_id > 0;

SELECT plc.file_id
    , plc.page_id
    , plc.slot_id
    , pk.*
FROM dbo.PKTest pk
CROSS APPLY fn_PhysLocCracker(%%PHYSLOC%%) plc;

結果、私の tempdbが、以下のとおりです。

ここに画像の説明を入力してください

上の画像では、最初の3列がfn_PhysLocCracker関数から出力され、ディスク上の行の物理的な順序を示しています。値は、クラスタリングキーslot_idであるc2値とともにロックステップを増加させることがわかります。主キーインデックスは行を異なる順序で格納します。これは、SQL Serverが主キーのスキャンから結果を返すように強制することで確認できます。

SELECT pkt.c1
    , pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN);

ORDER BY主キーインデックス内のアイテムの順序を表示しようとしているため、上記のステートメントでは句を使用していません。

上記のクエリの出力は次のとおりです。

ここに画像の説明を入力してください

見るとfn_PhysLocCracker機能、私たちは、主キーインデックスの物理的な順序を見ることができます。

SELECT plc.file_id
    , plc.page_id
    , plc.slot_id
    , pkt.c1
    , pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN)
CROSS APPLY fn_PhysLocCracker(%%PHYSLOC%%) plc;

インデックス自体からのみ読み取りを行っているため、クエリの中でインデックス外の列が参照されていないため、%%PHYSLOC%%値はインデックス自体のページを表しています。

結果:

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.