トップページへ PASSJ ブログへ
トップページへ
分科会
特集!
コミュニケーション
資格
セミナー・コンファレンス
インフォメーション
Oracleキーワードから学ぶ、逆引き! SQL Server入門
文=株式会社CSK 教育サービス事業部
第5回
アーキテクチャ編(2) スペシャルキーワード
索引
Oracle Serverの「索引」はSQL Serverでは「インデックス」と呼び、似て非なる部分の多いオブジェクトです。SQL Serverのインデックスには「クラスタ化インデックス」と「非クラスタ化インデックス」の2種類があります。

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


●テーブルスキャン

Oracle ServerでもSQL Serverでも、インデックス(索引)がないテーブルは全件検索を行うことになります。なぜならテーブルデータの並び順には何の保証もないからです。たとえば、社員テーブル1万件の中から「スズキ」という姓のデータを探すとき、スズキさんは何人いるかわかりませんので、もし結果として3人しかいなかったとしても1万件すべてを検索せざるを得ないのです。このテーブルを全件検索する処理のことを「テーブルスキャン」といいます(Oracleでは「全表走査」といいます)。

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

現実社会の「書籍」には、目的のキーワードをすばやく探すために、本文とは別に索引がついています。たとえば、調べたい単語があるときはABC順などに並んだ索引でその単語を探し、目的のページを見つけることができます。SQL Serverでは、この「書籍の索引」のように、(書籍の本文にあたる)テーブルデータとは別の領域に作られたインデックスを「非クラスタ化インデックス」といいます。「非クラスタ化インデックス」はOracle Serverの索引と同じですから、皆さんはすぐにどんなものか想像がつくでしょう。

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

SQL Serverにはもうひとつ、「クラスタ化インデックス」というインデックスがあります。どうせ条件を指定してデータを検索するのなら、テーブルデータ自体が何らかの基準に沿って並ぶように格納されていれば、その値を条件にした検索が早くなるだろうと思いませんか?Oracle Serverの「索引構成表」を思い出してください。テーブルのデータ自身がある基準に沿って並んでいますよね。現実社会で言えば、情報そのものが名前順や職業順に並んでいる「電話帳」のようなものです。電話帳で特定の人を探す作業は索引から実際の本文を探すより効率的です。

Oracle Serverの索引構成表では、1行がブロックサイズを越えるとオーバーフロー領域を使用するなど、非効率なところがあるという理由からあまり使用されることはありませんが、SQL Serverでは通常、テーブルにはクラスタ化インデックスを作成します。クラスタ化インデックスはデータ自体がある基準どおりに並ぶのですから、各テーブルに1つしか設定できません。テーブル自体がインデックスの構造を取るわけです。

テーブルに主キーを設定すると、その列に対してデフォルトで自動的にクラスタ化インデックスが作成されます。クラスタ化インデックスは、頻繁に範囲検索されるような列に作成するべきですが、もし主キーをクラスタ化インデックスにしたくないのであれば、設定時に「NONCLUSTEREDキーワード」を指定してください。



インデックスの構造とデータ検索のしくみ


SQL Serverのインデックスは、クラスタ化インデックス、非クラスタ化インデックスともにBツリー方式の構造をとっています。Oracle Serverの「ビットマップインデックス」に相当するものはありません。SQL Serverでは、Bツリーのルートからツリーをたどって目的のデータを探し出すことを「インデックスシーク」といいます。また、クラスタ化インデックスを作成したテーブルを全件検索するときなど、インデックスのリーフレベルのページチェーンをたどることを「インデックススキャン」といいます。パフォーマンスチューニングなどで「実行プラン」(Oracleの「実行計画」)を確認する場合に、結果に「インデックス」とあったとしても「スキャン」であれば全件検索している可能性もあるので、「スキャン」と「シーク」の違いは覚えておくべきでしょう。ちなみにSQL Serverでは「クエリオプティマイザ」という機能が、もっとも効率的な実行プランをコストベースで決定します。

さて、すでに説明した通り、SQL Serverでは通常クラスタ化インデックスを作成しますので、よくあるテーブルの構成としてはクラスタ化インデックスを作成したテーブルに、さらに非クラスタ化インデックスが複数作られます。このとき、非クラスタ化インデックスのリーフレベルには非クラスタ化インデックスのキー値と、さらに実データであるクラスタ化インデックスのキー値を持ちます。非クラスタ化インデックスを使用して実データを参照するような処理がおこなわれるときは、図のように非クラスタ化インデックスシークをした後に、クラスタ化インデックスのキー値をもとにクラスタ化インデックスをルートからたどって、実際のデータ(クラスタ化インデックスのリーフページ)にたどり着くのです。

■ クラスタ化インデックスを使用して実データを参照
クラスタ化インデックスを使用して実データを参照の図

インデックスは、値がある列の順番に並んでいるからこそ、新たにデータを挿入しようとしたときにページ分割が起こる可能性があります。たとえば社員番号がクラスタ化インデックスとして設定されているテーブルがあり、社員番号「100」「102」「103」の3レコードで「ページ」(Oracleのブロック)が一杯になっているとします。ここに新たに「101」を挿入すると、「100」「101」のページと「102」「103」のページに分割します。これに関しては、Oracle ServerもSQL Serverも同じ動きをします。ページ分割自体、システムのオーバーヘッドですので、Oracle Server、SQL Serverともにページ分割が起こらないようにインデックス作成時にある程度の空き領域を作っておきます。

Oracle Serverでは「PCTFREEパラメータ」でブロックの空き領域のパーセンテージを指定し、SQL Serverでは「CREATE INDEXステートメント」の「FILLFACTORオプション」で「何パーセント使用するか」を設定します。なお、FILLFACTOR値のデフォルトは0(100%使用)です。読取中心のOLAPのシステムではFILLFACTOR値は100%のままでも良いでしょう。FILLFACTORはクラスタ化インデックス、非クラスタ化インデックスともに、リーフレベルページの使用率として設定できます。

Oracle Serverでは「表」に対してもUPDATEの空き領域としてPCTFREE設定できますが、SQL Serverはクラスタ化インデックスを作成していないテーブルのページに対して、使用率は指定できません。FILLFACTOR値はあくまでインデックスのリーフレベルページに適用するものです。しかし通常はテーブルにクラスタ化インデックスを作成しますので、インデックスに対するFILLFACTORの設定ができれば問題ないわけです。

ページ分割による断片化の解消方法など、インデックスの保守の詳細はマイクロソフト認定トレーニングコース「#2073 Microsoft SQL Server 2000 データベースプログラミング」で扱っています。




・ 第1回 基本用語編:データベースオブジェクト
・ 第2回 ユーティリティ編:SQL*Plus
・ 第3回 アーキテクチャ編(1):インスタンスとデータベース
・ 第4回 アーキテクチャ編(2):セグメント/エクステント/データブロック
・ 第5回 アーキテクチャ編(3):索引
・ 第6回 プログラミング編:カーソル
・ 第7回 トランザクション/ロック編:読み取り一貫性
・ 第8回 バックアップとリカバリ編:スタンバイ・データベース
・ 第9回 ユーザー管理編:ロール
・ 第10回 パフォーマンスチューニング編:EXPLAIN PLAN(実行プランの表示)


著者プロフィール
株式会社CSK 教育サービス事業部
http://www.cskedu.com/
OracleとSQL Server、それぞれのトレーニングコースを担当するトレーナー3名体制で執筆しています。メンバーは、金子真由美、浦山裕恭、浅見淳子。
今回の執筆担当
金子真由美(KANEKO, Mayumi)
マイクロソフト認定トレーナーとして、SQL Serverを中心にトレーニングを担当しています。Oracleを使用したシステム開発の経験を活かし、OracleやDB2などの動きを踏まえたSQL Serverのトレーニングや執筆を行っています。忙しい毎日ですが、「緑の中での白い玉打ち」だけはやめられません。

← 特集!DBバイリンガル 目次

PASSJメールニュース 著作権ついて プライバシーポリシー リンクポリシー お問い合わせ
(C) 2005 Professional Association for SQL Server Japan. All rights reserved.