実行計画を理解するには、まずそれを理解してから、あらゆる種類の名詞を理解する必要があります。よくわからないので。この記事は、理解されているが理解されていない場合にのみ書かれることを意図しています。
最初に、実行プランを初めて見るときは、SQL Serverの実行プランが右から左に表示されていることに注意する必要があります。
名詞分析:
スキャン:データを1行ずつ走査します。
最初にテーブルを作成し、それがどのように見えるかを示します。
CREATE TABLE 人( 同上のint型の IDENTITY(1、1)NOT NULL 、 名前NVARCHAR(50)NULL 、 年齢int型の NULL 、 高さint型の NULL 、 エリアNVARCHAR(50)NULL 、 MarryHistory NVARCHAR(10)NULL 、 EducationalBackgroundのデータ型はnvarchar(10)NULL 、 アドレスnvarchar(50)NULL 、 InSiteId int NULL )ON [ PRIMARY ]
テーブルのデータは約140,000で、次のようになります。
このテーブルにはインデックスがありません。
1.データアクセス操作
1.テーブルスキャン
テーブルスキャン:ヒープテーブルが発生し、使用可能なインデックスが利用できない場合、テーブルスキャンが発生し、テーブル全体が1回スキャンされることを示します。
次に、このテーブルで簡単なクエリステートメントを実行してみましょう。
SELECT * From Person WHERE Name = ' 公子'
次のように実行プランを表示します。
テーブルスキャンは、その名前が示すように、テーブル全体をスキャンして必要なデータを見つけることです。
2.クラスター化インデックススキャン
クラスター化インデックススキャン:クラスター化テーブルで発生します。これも全テーブルスキャン操作と同じですが、クラスター化列の条件が(WHERE Id> 10)である場合、その他の操作を行うと効率が向上します。
次に、クラスター化インデックスをこのテーブルのId列に追加します
CREATE CLUSTERED INDEX IX_Id ONパーソン(同上)
同じクエリをもう一度実行します。
SELECT * From Person WHERE Name = ' 公子'
実行計画は次のとおりです。
Id列に構築されたクラスター化インデックスがスキャンに影響するのはなぜですか?名前条件とは何の関係もないことは言うまでもありませんか?
実際、クラスター化インデックスを追加すると、テーブルはヒープテーブルからクラスター化テーブルに変わります。クラスタ化テーブルのデータは、クラスタ化インデックスのリーフレベルノードに存在することがわかっています。したがって、集計スキャンはテーブルスキャンと大きな違いはなく、大きな違いがある場合は、where条件の内容と後で返されるデータによって異なります。このSQLステートメントに関する限り、効率に大きな違いはありません。
あなたはI / O統計を見ることができます:
テーブルスキャン:
クラスター化インデックススキャン:
これはこの記事の範囲を超えており、効率はこの記事の範囲内ではありません。この記事では、さまざまなスキャンの違いとその原因についてのみ検討します。
3.クラスター化インデックスの検索
クラスター化インデックスのルックアップ:クラスター化インデックス内の特定の範囲の行をスキャンします。
次のSQLステートメントの実行を見てください。
SELECT * FROM Person WHERE Id = ' 73164 '
実行計画は次のとおりです。
4.インデックススキャン
インデックススキャン:非クラスター化インデックス全体をスキャンします。
クラスタ化インデックスを追加して、クエリステートメントを実行してみましょう。
CREATE NONCLUSTERED INDEX IX_Name ON Person(Name) -create a non-clustered index SELECT Name FROM Person
次のように実行プランを表示します。
ここでインデックススキャン(非クラスター化インデックス)を選択する理由
この非クラスタ化インデックスは必要なデータをカバーできるためです。非クラスター化インデックスをカバーできない場合はどうなりますか?たとえば、SELECTをSELECT *に変更して確認します。
明らかに、返される結果に含まれるレコードが多すぎるため、非クラスター化インデックスを使用するのは費用対効果が高くありません。したがって、クラスター化インデックスが使用されます。
この時点でクラスター化インデックスを削除した場合は、SELECT *を実行して確認します。
DROP INDEX Person.IX_Id
現時点ではクラスター化インデックスがないため、テーブルスキャンのみが使用されます。
5.ブックマーク検索
インデックス作成に関する以前の調査では、非クラスター化インデックスが必要な列をすべて網羅していない場合、SQL Serverはクラスター化インデックススキャンを直接実行してデータを取得するか、非クラスター化インデックスに移動してクラスター化インデックスキーを見つけることを既に知っています。次に、クラスター化インデックスを使用してデータを検索します。
ブックマーク検索の例を見てみましょう:
SELECT * FROM Person WHERE Name = ' Fatty ' --Name列に非クラスター化インデックスがあります
実行計画は次のとおりです。
上記のプロセスは次のように理解できます。最初に、非クラスター化インデックスを通じて要求された行を見つけますが、このインデックスにはすべての列が含まれていないため、基本テーブルに移動してこれらの列を見つける必要があるため、基本テーブルがヒープによって編成され、このキールックアップ(キールックアップ)はRIDルックアップ(RIDルックアップ)になり、キールックアップとRIDルックアップはまとめてブックマークルックアップと呼ばれます。ただし、非クラスター化インデックスによって返される行数が多すぎる場合、SQL Serverはクラスター化インデックススキャンを直接実行することを選択することがあります。
第二に、フロー集約操作
1.ストリーム集約
ストリーム集約:対応するソート済みストリーム内の複数の行セットの合計値を計算します。
すべての集計関数(COUNT()、MAX()など)にはストリーム集計がありますが、IOは消費せず、CPUのみを消費します。
たとえば、次のステートメントを実行します。
SELECT MAX(年齢)FROM人
次のように実行プランを表示します。
2.スカラーを計算する
スカラーの計算:行の既存の値に基づいて新しい値を計算します。たとえば、COUNT()関数では、行がもう1つある場合、行の数は1つ増えます。
MIN関数とMAX関数以外の集計関数では、ストリーム集計操作の後に計算スカラーが必要です。
SELECT COUNT(*)FROM人
次のように実行プランを表示します。
3.ハッシュ集約(ハッシュ照合)
Group byが追加された句の場合、データはgroup byの後ろの列に従って順序付けされる必要があるため、確実にソートするためにSortが必要です。なお、Sort操作はメモリを占有する操作であり、メモリが不足するとtempdbも占有します。SQL Serverは常に、ソート操作とハッシュマッチングの中で最も低いコストを選択します。
高さを 選択、COUNT(Id)FROM人- グループBYの高さを調べる BY高さ
実行計画は次のとおりです。
データボリュームが大きい場合、SQL Serverはハッシュマッチングを選択します。
ハッシュテーブルがメモリに作成された後、group byに続く値がキーとして使用され、コレクション内の各データが順番に処理されます。キーがハッシュテーブルに存在しない場合は、ハッシュテーブルにエントリを追加します。リストが存在する場合、ハッシュテーブルの値はルールに従って計算されます(ルールはSum、avgなどの集計関数です)。
4.ソート
たとえば、データ量が少ない場合は、次のステートメントを実行して、Personと同じ数十のレコードのみを含む新しいテーブルを作成します。
SELECT * INTO Person2 FROM Person2 WHERE Id < 100
次に、同じクエリステートメントを実行します。
SELECT Height、COUNT(Id)FROM Person2-しかし 、テーブルはデータ量の少ないテーブルに置き換えられます GROUP BY Height
実行計画は次のとおりです。
3.接続
マルチテーブル結合(ブックマーク検索とインデックス間の結合を含む)の場合、SQL Serverは、3つの異なるタイプの結合を使用します。ループネスト結合、マージ結合、ハッシュ結合です。これらのいくつかの接続形式には独自のシナリオがあり、より良い言い方はありません。
次のように2つの新しいテーブルを作成します。
これは単純なニュースの列構造です。
1.ネストされたループ
まず、単純な内部結合クエリステートメントを見てください。
SELECT * FROM Nx_Column AS C INNER JOIN Nx_Article AS A ON A.ColumnId = C.ColumnId
実行計画は次のとおりです。
ループネスト接続のアイコンも非常に鮮やかで、上部の外部入力(外部入力)にあります。これもクラスター化インデックススキャンです。そして、以下の内部入力(Inner Input)は、クラスター化インデックスのルックアップです。外部入力は1回だけ実行され、内部入力は、外部入力が結合条件を満たす各行に従って検索されます。ここには7行あるため、内部入力は7回実行されます。
ネストされたループの原理によれば、外部入力がスキャンで内部入力が検索であるため、2つの結合テーブルの外部入力結果セットが比較的小さく、内部入力によって検索されるテーブルが非常に大きい場合、クエリオプティマイザーはより傾斜していることがわかります。ループのネスト方法を選択します。
2.接続をマージ
ネストされたループとは異なり、マージ結合は各テーブルから1つのアクセスのみを実行します。この原則から、結合のマージはループのネストよりもはるかに高速です。
結合の結合の原理から想像するのは難しくありません。最初に、結合を結合するには、両方のパーティが正しいことが必要であり、結合の条件は符号と同じです。2つの入力条件は既に順序付けされているため、比較のために各入力セットから行を取得し、等しいものを返し、等しくないものを破棄します。マージ結合が等号の後にのみ結合を許可する理由を理解することは難しくありません。この原則は、図11のアイコンから確認できます。
SELECT * FROM Nx_Column AS C INNER JOIN Nx_Article AS A ON A.ColumnId = C.ColumnId OPTION(MERGE join)
実行計画は次のとおりです。
入力データの両側が順不同である場合、クエリアナライザーはマージ接続を選択しません。マージプロンプトを使用して強制的にマージ接続を行うこともできます。これを実現するには、実行プランで並べ替え手順を追加して順序を実現する必要があります。これが、上記のSQLステートメントがOPTION(MERGE結合)を追加する必要がある理由です。ArticleテーブルのColumnId列は、上記のようにソートされます。
3.ハッシュ接続
また、ハッシュ接続は、両方のパーティのデータに一度だけアクセスする必要があります。ハッシュ結合は、メモリ内にハッシュテーブルを作成することで実現されます。これはメモリを集中的に使用するため、メモリが不足している場合はtempdbを使用することもできます。しかし、それはマージされた接続ほど整然としていない。
次の2つの実装を実行するには、2つの列のクラスター化インデックスをColumnId列に構築しないでください。構築しないと、ハッシュ結合が使用されません。
ALTER TABLE PK_Nx_Column DROP CONSTRAINT PK_Nx_Column -ドロッププライマリ DROP INDEX Nx_Column.PK_Nx_Column -クラスタ化インデックスドロップ CREATE CLUSTERED INDEX IX_ColumnName ON Nx_Column(ColumnNameには) クラスタ化インデックスを作成する- -クラスタ化インデックスでここに戻って上の主キーにし、デフォルトでは主キーで構築できません
また、別のテーブルアーティクルのクラスター化インデックスを削除します。
次に、次のクエリを実行します。
SELECT * FROM Nx_Column AS C INNER JOIN Nx_Article AS A ON A.ColumnId = C.ColumnId
実行計画は次のとおりです。
クラスター化インデックスを削除するには、それ以外の場合、2つの順序付けされた入力SQL Serverが低コストのマージ接続を選択します。SQL Serverは、上記の2つの入力を使用してハッシュテーブルを生成し、次の入力を検出して検出します。この情報は、図15に示すように、プロパティウィンドウで確認できます。
一般的に言えば、一方または両方の当事者が注文されていないときに要求されたデータが満たされると、ハッシュ照合が使用されます。
4、並列
複数のテーブルが接続されている場合、SQL Serverは、複数のCPUまたは複数のコアの場合にクエリの並列処理を許可します。これにより、間違いなく効率が向上します。
偉大な神の説明を転載し、元のテキストは次のとおりです。http://www.cnblogs.com/kissdodog/p/3160560.html