2016-05-26 2 views
3

私はインタビューの準備をしていて、ちょうどこれらのことに来ています。テーブル内のレコードのソートがクラスタ化インデックスごとに行われないのはなぜですか?

私は、次のステートメントを実行している:ここに示されているよう

create table trial 
(
    Id int not null, 
    Name varchar(10) 
) 

alter table trial add constraint unq unique clustered (Name) 

alter table trial add constraint pk primary key nonclustered(Id) 

insert into trial values (1,'a'),(3,'d'),(5,'b'),(2,'c') 

select * from trial 

結果は次のとおりです。

enter image description here

私の質問は次のとおりです。名前の列がクラスタ化されたように、結果は、名前の欄ごとにソートされていないのはなぜインデックス?

結果は次のとおりです。

1 a 
2 c 
3 d 
5 b 

テーブルの物理的なソートにインデックスを使用する方法は?

+0

使用するdbmsにタグを付けます。 (インデックスは常に多かれ少なかれ製品特有です。) – jarlh

+0

MS SQL 2014開発者版 – Sagar

+0

トピックに関するこの記事を読んでください。 https://blogs.msdn.microsoft.com/conor_cunningham_msft/2008/08/27/no-seatbelt-expecting-order-without-order-by/ –

答えて

2

この場合、オプティマイザは非常に小さいため、フル・テーブル・スキャンまたはノンクラスタード・インデックス・スキャンを実行することにしました。あなたは、実際の実行プランを含めると、この見ることができます:あなたはクラスタ化インデックスを使用するように強制することができ

enter image description here

SELECT * FROM TRIAL WITH (INDEX(UNQ)) 

をそして、あなたはおそらく取得します:

enter image description here

をし、結果セット:

Id Name 
1 a 
5 b 
2 c 
3 d 

しかし、注文はまだ保証されていないので、実際にはこれを行うべきではありません。結果をいくつかの列でソートする場合は、明示的に行います。あなたには、いくつかの良い説明を得ることができる場所

は、私は本Exam 70-461: Querying Microsoft SQL Server 2012からの断片をコピーします。

それは、出力はEMPIDでソートされているように見えるかもしれませんが、それは保証さ ではありません。もっと混乱する可能性があるのは、クエリ を繰り返し実行すると、結果が同じように返され続けるようです。 オーダー。しかし、それは保証されていません。データベースエンジン(この場合はSQL サーバ)がこのクエリを処理するとき、 に特定の順序でデータを返す明示的な指示がないので、 のデータを任意の順序で返すことができることがわかります。 の最適化およびその他の理由により、SQL Serverデータベースエンジンは、今回は特定の方法でデータを処理するために を選択した可能性があります。物理的な状況が同じままであれば、そのような選択肢が繰り返される可能性もあります。 しかし、 の間には、最適化やその他の理由により何が起こる可能性がありますか? 実際に保証されるものには大きな違いがあります。

が返される順序に影響を与える可能性のあるデータベースエンジンを、場合によっては が変更すると、自由に実行できることがわかります。このような変更の例としては、データ配信の変更、インデックスなどの物理構造の の可用性、CPUおよびメモリなどのリソース の可用性などの選択肢の変更が含まれます( )。また、 の製品の新しいバージョンにアップグレードした後、またはサービスパックのアプリケーション の後であっても、エンジンが変更されると、最適化の側面が変わることがあります。同様に、そのような の変更は、とりわけ、 結果の行の順序に影響を与える可能性があります。要するに

、これは十分に強調することはできません。 をしないクエリが結果内の行の順序を保証するものではありません 特定の順序で行を返すように明示的な指示を持っています。 がそのような保証を必要とする場合、それを提供する唯一の方法は、ORDER BY 句をクエリに追加することです。これは次のセクションの焦点です。

コメントに基づいてEDIT:

事はあなたがクラスタ化インデックスを使用している場合でも、それは順不同セットを返すことです。 (1, 2, 3, 4, 5)のようなクラスタ化キーの物理的な順序があるとします。ほとんどの場合、(1, 2, 3, 4, 5)が得られますが、オプティマイザはのパラレルリードをと読んで、2つのパラレルリードを持ち、(1, 2, 3)(4, 5)と読みます。今すぐ(4, 5)が返されてから(1, 2, 3)が返されることがあります。 order by句エンジンがない場合は、そのリソースをそのリソースセットに費やさずに、(4, 5, 1, 2, 3)を与えます。したがって、注文するときに必ずorder by句があることを確認する必要があります。

+0

ありがとうございます。実際に私が知っていたのは、テーブル内のレコードの物理的な順序付けは、常にクラスタ化されたインデックスごとです。 ..しかし私は間違っていた... – Sagar

+0

@サガール、いいえあなたはそれに正しかった。私はその答えをより詳細に説明します。 –

+0

thanx ..私はその答えに本当に満足しています。並列読み込み...正しい。 – Sagar

4

リピート:SQLテーブルは、の順不同で表します。セット。問合せにorder by句が含まれていない限り、SQL結果セットはの順不同でです。あなたは順番にデータが必要な場合は

ので、その後、order byを使用します。

select t.* 
from trial t 
order by t.name; 

あなたが特定の順序で結果をしたい場合は、order byを使用しています。 SQL Serverには最適なオプティマイザがあります。実際のソートを避けるためにクエリのインデックスを使用できる場合、通常はインデックスを使用します。

+0

はい私は知っている..なぜテーブルのレコードがソートされていないのかクラスタ化インデックス?? – Sagar

+0

申し訳ありませんが、レコードがテーブル内でどのようにソートされるかを知る方法がありません。照会の際にレコードがどのように返されるのかしかわかりません。指定された順序を要求しない限り、これは純粋にSQL内部の不確定なものです。 – Arvo

+0

@Sager。 。 。問題は、テーブルのソート方法ではありません。問題はクエリがどのように機能するかです。ページのデータ・ダンプを実行した場合、実際にはデータ・ページでデータが順序付けられていることがわかります。しかし、クエリはそれを尊重する必要はありません。 –

関連する問題