14
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【SQLServer】パフォーマンスを意識したSQL

Last updated at Posted at 2018-10-01

前に調べた記事の内容を見返しながら、再度「自分の中で押さえておきたいポイント」を整理してみた。
※せっかくまとめたけど、しばらくSQLServerは使わなそう...残念。

インデックスの種類

そもそもインデックスって?

テーブルやビューからの行取得を高速に行うためのもの。
SQLServerの場合は「B-Tree構造」で作成され、指定したキーで昇順に並び替えられたデータの範囲によって枝分かれしている。

クラスター化インデックス

リーフレベルに、「実際のデータそのもの」が格納されている。
クラスター化インデックスが作成されると、非クラスター化インデックスのリーフレベルには
「ポインタ(RID)」ではなく「クラスター化インデックスの値」が格納される。
そのため、実際のデータを探すことなく(RID Lookup)することなく、インデックスをSeekするのみで検索が可能になる。
また、クラスター化インデックスは「テーブルに1つのみ作成可能」で、デフォルトでは主キーの値で作成される。

非クラスター化インデックス

リーフレベルに「実際のデータへのポインタ(RID)」が格納されており、インデックスの走査後にポインタを元にデータを取得する。
この実データへのアクセスを「ページジャンプ」という。
また、クラスタ化インデックスがテーブルに作成されている場合は、「クラスター化インデックスのキー」が格納されているため、クラスター化インデックスからデータを取り出す処理となる(Key Lookup)。

複合インデックス(カバリングインデックス)

複数カラムをインデックスキーに指定したもの。
複合インデックスでもリーフノードからの「ページジャンプ」を行って、実データへのアクセスを行う。
しかし利用したいデータが「複合インデックスのキー」に含まれている場合、実データ領域へのアクセスをすることなくデータを取得することができる。
これを活かして、「取得するデータをインデックスに全て含めてしまおう」というのが「カバリングインデックス」。
ただしすべてのノードに複数カラムのデータを保持するため、インデックスのサイズが大きくなってしまう。

付加列インデックス

すべてのノードに複数カラムのデータを保持するのではなく、リーフノードにのみカラムを追加する(列を付加する)ことで、
ページジャンプを防ぎながらインデックスサイズを押さえることもできる。
「WHERE句に指定するカラムをキーに指定し、取得するカラムを付加しておく」といった使い方をする。

#データへのアクセス

Index Seek, Clusterd Index Seek

Bツリーを走査したあと、一致するデータを見つけるためにリーフノードを検索する。

Index Scan, Clusterd Index Scan

インデックスのツリー構造を使った走査を行わず、リーフノードを順番に検索する。
Index Seekよりも多くのページにアクセスすることになるため、非効率な検索方法といえる。

Key Lookup(Clusterd)

非クラスタ化インデックスのリーフノードに格納された「クラスター化インデックスのキー」を基に、クラスター化インデックスから1行を取り出す。

RID Lookup(Heap)

非クラスタ化インデックスのリーフノードに格納された「RID(行識別子)」を基に、実テーブルから1行を取り出す。

なぜIndex Scanになってしまうのか

WHERE句の左辺に関数を使用している

せっかく値が入っているのに、関数を使ってしまったらインデックスの値で探せなくなってしまう。

インデックスが張ってある列の一部しか条件指定していない、または順番が間違っている

インデックスは「指定したキーでデータが並んでいる」ため、そのキーの一部しか条件に指定しなかった場合、正しくインデックスをSeekせずにScanしてしまう。

パフォーマンス

Index ScanからIndex Seekに

↑に書いたような点を意識してSQLを見直す。
正しくインデックスが利用されるようなSQLにすることで、Index Seekにする。

Key LookupやRID Lookupを無くす

クエリのチューニングをするためには、「クエリによって行われる読み取り数を減らす」ことが重要。

参考URL

14
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?