0LINEはじめにデータベースのインデックスについて、インデックスの種類、内部の仕組み、select時の動きを図解してまとめました。大きいテーブルで4億レコードほど登録した状態でのオンライン処理(検索処理)や、300万レコードを3~4時間以内に集計するバッチ処理を作ることになりました。同じような問題を抱えておられる方向けに、この記事をまとめました。Serverのインデックスの種類と内部の仕組みについて理解しておくポイントは以下の3つです。インデックスの目的とデータ構造データページとインデックスページの関係select時のインデックス利用イメージDBAの方からすると当たり前だと思いますが、アプリケーションエンジニアの方でこの辺りを理解してインデックスを貼ったり開発している人にあまり出会ったことがないです。ここを理解してアプリケーションを作成できると性能問題に苦しまなくて済むので是非理解しておいてください。無駄なデータにアクセスすることなく目的のデータにアクセスする(IO回数を減らす)ことです。ServerのインデックスはB-Tree型です。下が何も使わずに特定データを取得するイメージです。黄色の部分がIOしている箇所とすると、インデックスを利用した方がIO回数が減らせている(黄色が少ない)ことが分かります。データページとインデックスページの関係テーブル内の具体的なデータは、データページというところに格納され、インデックスはインデックスページというところに格納されます。Serverにはクラスター化インデックスと非クラスター化インデックスの2種類があります。図のように、クラスター化インデックスはB-Treeのリーフ部(一番下の層)のみがデータページに格納されます。実際のテーブルのデータを特定のkeyの順番で並ばせるので1テーブルに1つしかクラスター化インデックスは貼れません。非クラスター化インデックスはB-Treeのリーフ部も含めてインデックスページに入り、リーフ部には該当データへのポインタが格納されます。非クラスター化インデックスは数レコードのみを取得する必要がある場合に有効です。非クラスター化インデックスはB-Treeを辿ってさらにポインタで実データを見に行く必要があります。(ただしインデックスを貼ったカラムのみselectする場合はB-Treeに情報があるためデータページを見る必要はない)自分はできる限り、B-Treeを辿るだけで完結するようにインデックスを貼ることを意識しています。SQLServerのチューニングアドバイザもそのように指摘してきます。非クラスタ化インデックスをクラスタ化インデックスのようにB-Treeをたどるだけで完結させるにはカバリングインデックスか付加列インデックスを作成すれば良いです。Server2005以降を利用している場合は付加列インデックスを使う方べきです。理由は後述の通りです。非クラスタ化インデックスを利用した場合、先ほどの絵のように、IDカラムのB-Treeを辿る+ポインタで実レコードを特定してName情報を取得する必要があります。非クラスタ化インデックスのカバリングインデックスや付加列インデックスを利用した場合を絵にすると、カバリングインデックスではIdとNameの情報がB-Treeの全ノードあるため、ポインタで実データを見に行く必要がありません。付加列インデックスではB-Treeのリーフ部にのみNameの情報があるため、B-Treeを辿った後にポインタで実データを見に行く必要がありません。該当レコードをポインタで見にいく必要があるかないかで性能は大きく変わります。カバリングインデックスと付加列インデックスの特徴を比較すると以下のようになります。Server2005より前のバージョンを利用していない限り付加列インデックスを利用すべきです。Serverのインデックスの種類と内部の仕組みについて説明しました。意識しているポイントは以下3つです。インデックスを貼る際、無駄にストレージを圧迫させないインデックス更新時のオーバーヘッドをできる限り減らすデータページへのインデックスを参照できる限りさせないために付加列インデックスを有効活用するこの辺りを意識せずにモノができて最後の性能測定をして大惨事にならないように、DBAだけでなくアプリケーション開発に関わるメンバー全員が意識できるとリリース間際にバタバタしなくて済むと思いますが、それが難しい。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。