目次


DB2 ストレージあれこれ

Comments

DB2 ストレージのマクロ管理

リレーショナル・データベースは、データの論理的なビューしか提示しません。それにもかかわらず、我々はなぜデータの物理的な配置を心配するのでしょうか。理由はいくつかあります。まず、ストレージ・システムのすべてのディスクが同じアクセス速度を備えているとは限らないことです。DB2に割り当てて管理できるすべてのハードウェアが等しくないとすると、データも等しくない可能性があります。これが本当であれば、アクセス頻度が最も低いデータを最も速度の遅いデバイスに保存する価値があるかもしれません。

第2に、あなたは自分のデータについてDB2が知り得ない次のようなことを知っているかもしれないということです。

  • ある月の予測売上など、将来の見通し,
  • 市外局番が2つに分かれるときなどの電話番号の変更 (これにより主キーが変更されます)
  • または買収予定の企業 (この企業には既存のスキーマにマージしなければならない独自のデータがあります) など

心当たりがない場合は、月並みですが「見つけることができなければ管理できない」と納得して、この記事を読み進んでください。

では、基本から始めましょう。DB2のサイズ制限は? この質問の回答はまず、『 SQL 解説書 』の付録Aを参照してください。この付録では一般的な制限値を説明しています。以下は、ストレージの制限値の一覧です。この一部は『 SQL解説書 』に記載されています。また、これらは絶対制限値でもあります。特定のページ・サイズで強制される制限については、付録Aの最後の表「データベース・マネージャーのページ・サイズ固有の制限値」を参照してください。一部の制限値は「区画あたり」または「ノードあたり」のものであることに注意してください。これらは、 DB2パーソナル・エディション、ワークグループ・エディションおよびエンタープライズ・エディションの絶対制限値ですが、エンタープライズ拡張エディションでは、この値に999を掛けることができます。(区画として知られる999のノードを含めることができます)

SMS表スペースの最大表数65 534
DMS表スペースの最大表数51 000
データベースの最大表スぺース数4096
表の列の最大数500〜1012 (ページ・サイズによって異なる)
ビューの列の最大数5 000
行の最大長 (すべてのオーバーヘッドを含む) 4005〜32 677バイト (ページ・サイズによって異なる)
VARCHAR の最大長32 672バイト
長形式フィールド (CLOB、BLOB) の最大長2GB
区画当たりの表の最大サイズ64-512GB (ページ・サイズによって異なる)
区画当たりの索引の最大サイズ64-512GB (ページ・サイズによって異なる)
区画当たりの表内の最大行数4,000,000,000
索引キーの最大長 (すべてのオーバーヘッドを含む)1024バイト
索引キーの列の最大数16
表の最大索引数32 767または記憶域
SQLテートメント/ビューで参照される表の最大数記憶域
SQLステートメント中のホスト変数参照の最大数32 767
SQLステートメントの最大長 (バイト単位) 65 535
選択リストの最大エレメント数1012
表に対する制約の最大数記憶域
INSERTステートメント中の値の最大数1012
ユニーク制約の列の最大数(ユニーク索引によってサポートされる) 16
ユニーク制約の列の結合後の最大長(ユニーク索引によってサポートされる) 1012
参照される列の結合後の最大長1024
区分化キー内の列の最大数500
サーバーの並行ユーザーの最大数64 000
トリガーのカスケード実行時の最大の深さ16
正規DMS表スペースの最大サイズ512GB
長形式DMS表スペースの最大サイズ2TB
一時DMS表スペースの最大サイズ2TB
インスタンス当たりの並行ユーザーの最大数64 000
最大区画番号999
DMS表スペースの表オブジェクトの最大数51 000
最大データベース (長形式フィールドを除く) 4096*65,535*0.5TB
最大EEE データベース (LONGフィールドを除く) 4096*65,535*0.5TB * 999 ノード

制限値を左右する選択には、基本的に以下の3つがあります。

  • EEE 対 非区分データベース (ワークグループ・エディションまたはエンタープライズ・エディションなど)
  • ページ・サイズ 4K、8K、16K、32K の選択
  • SMS 表スペース 対 DMS 表スペース (システム管理かデータベース管理)

EEE 対 非区分データベース
DB2データベースのほかのエディションではなくエンタープライズ拡張エディション (EEE) を選択すると、物理的な制限値の多くが 3 桁ほど上昇するため、これが頑丈な壁 (または各ユーザーにとってそれに相当するもの) を打ち破るための簡単な武器となります。EEE を選択した場合の影響と利点については以下の 2 つの記事で考察しています。

  1. http://www7b.boulder.ibm.com/dmdd/library/techarticle/adamache/0430_adamache2.html (英文)
  2. http://www7b.boulder.ibm.com/dmdd/library/techarticle/adamache/0529_adamache.html日本語あり)

ページ・サイズ4K,8K,16K,32Kの選択
4Kページがデフォルトです。他のページ・サイズについては、該当するページ・サイズのバッファー・プール、表スペース、および一時表スペースを作成する必要があります。大きなページ・サイズの主な利点は、以下を保管できる表にあります。

  • より多くのデータ (4Kページ・サイズで64GB。8K、16K と、ページ・サイズが倍増するごとに倍増し、32Kでは512GBになります。)
  • より多くの列 (4Kページ・サイズでは500列。それ以上のページ・サイズではすべて1012列)
  • より広い行幅 (4005、8101、16 293、または 32 677 バイト)
  • より広いVARCHAR幅 (行幅とほぼ同じ)

SMS表スペース vs DMS表スペース (システム管理 vs データベース管理): 生と調理済み

SMSは System Managed Storage (システム管理ストレージ) の略です。すべての DB2オブジェクトはファイル・システムを使用してオペレーティング・システムによって管理されます。これは、一時表スペースのように急速に拡大/縮小する表スペースや、保守や監視をあまりできないデータベースにあるすべてのデータに理想的です。DMS (Database Managed Storage: データベース管理ストレージ) では、データの増加を予測することや、ディスク・スペースが不足している表スペースにコンテナーを追加できる状態にあることが必要になります。コンテナーは、ファイル・システム内のファイルの場合もありますが、ロウ・デバイスの場合もあります。ロウ・デバイス (およびロウ・ログ) 上の DMS 表スペースは「ロウ (生)」と呼ばれます。ファイル・システムを使用するSMS表スペースと DMS 表スペースは「クックド (調理済み)」と呼ばれます。(これはおそらく英国のロックグループのファイン・ヤング・キャニバルズやフランス社会人類学者のクロード・レヴィ・ストロースに敬意を表しているためでしょう)

まず、SMSとDMSを位置付けましょう。

 SMS DMS
ストライピング (並列 I/O の場合はどちらもデータのストライピングが可能)YesYes
オブジェクト管理オペレーティング・システム (固有ファイル名による)DB2
スペース割り当てオンデマンドで拡大/縮小事前割り当て
管理の簡易性DBA集中
パフォーマンス

上記の2つ目の参照記事でも触れているように、システム管理ストレージ (SMS) 表スペースは、システム・データ (一時表スペースとカタログ表スペース) およびデータベースに適しています。これらのデータベースの保守レベルは低くある必要があります。それは、数が多すぎるため設計や保守への多額の投資を正当化できないためです。一時表スペースは、ディスク・スペースの急速な割り当ておよび割り当て解除を必要とするため、SMSの選択が効果的です。

DMSでは、表のデータ、長形式フィールド (LOBなど) および索引を、最高3つまでの異なる表スペースに入れることができます。これにより、長形式フィールドを速度のより遅いディスクに保存したり、索引を高速のディスクに入れたりすることを選択できます。また、より細分化したバックアップおよび復元オプションが使用可能になります。長形式フィールド (LOBまたは LONG VARCHAR) には、ファイル・システム・コンテナーとともにSMSまたはDMSを使用します。LONG VARCHARは避けてください。VARCHAR でも長さはあまり変わらないうえ、LONG VARCHAR は、機能や標準の遵守の面でLOBの絶対サブセットです。LONG VARCHAR は、DB2 バージョン1の名残のデータ・タイプにすぎませんが、DB2はこれをサポートしています。

SMSでもDMSでも長形式フィールドをファイル・システム上のコンテナーに入れると、オペレーティング・システムのファイル・システム・キャッシュを利用することができます。DB2 は、長形式フィールドのキャッシュにバッファー・プールにある自分のメモリーを使用しません。カタログ表スペースには、ファイル・システム・コンテナーおよび小さなエクステント・サイズ (2または 4ページ) とともにSMSまたはDMSを使用します。カタログ表スペースには比較的小さな表が多数あり、DMSでは1つの表に必要になるオーバーヘッド・エクステントが2倍になります (SMSの場合は 2:1)。また、カタログ表には複数のLOB列があり、それらも前述したユーザーLOBと同じようにファイル・システム・キャッシングの恩恵にあずかります。

通常のユーザー・データにSMSを選択するか DMS を選択するかはいくつかの要因によります。ファイル・システム上の DMS は、SMSとDMSの弱みを併せ持っているので、使用しないようにしてください。(ロウ・デバイスと比べてファイル・システムの速度が遅くなる可能性がありますが、表の拡大につれて必要なコンテナーを追加するために拡大を予測/測定する追加の管理作業が必要であるのは同じです。) 特に AIX や Solaris の最新リリースのように先進的なファイル・システム装備の洗練されたオペレーティング・システムを使用している場合などに、最大の便宜を図って非常に優れたパフォーマンスを達成するには、SMS を選択してください。これらのオペレーティング・システムは重要なファイルをメモリーに効果的にキャッシュします。パフォーマンスを最大化するためには、ロウ・コンテナーのあるDMSを選択してください。通常、ロウ・コンテナーはファイル・コンテナーの性能を凌ぎます。それは、ロウ・コンテナーは、DB2がデータを読み込む際、オペレーティング・システムとそのファイル・システムを通した余分なパスを避けるからです。

複数の表スペースへの表の割り当て方の決定はいくつかの要因に基づきます。DB2 for OS/390では、DBAは各表を独自の表スペースに入れることを好む傾向にあります。Unix と Windowsでは、これが必ずしもDB2に適しているわけではありません。ロールフォワード・ポイントを使用して、検査保留状態 (RI 関係にある表が異なる時点のものである場合、参照制約違反で DB2によってそれらの表が凍結された状態) を回避したい場合は、参照保全性を通して関連する表は同じ表スペースに入れてください。また一方で、DB2 バージョン7.2以上ではLOADは表スペースへの排他的アクセスを必要とするため、LOADのターゲットである表は独自の表スペースに入れる必要があります (この制約は将来解除される予定です)。では、RI を必要とする表へLOADする場合はどうでしょう。これらの表も同じ表スペースに保管されていなければなりません。これらの表はRIでリンクされているため、LOAD中にその1つがオフラインになっている場合、残りの表に対するトランザクションも実行しないほうがいいでしょう。RI 関係にあり、LOAD中でない表に対して SELECTを許可する場合は、それらを異なる表スペースに入れてください。

DB2 ストレージのマイクロ管理

前述の「ストレージのマクロ管理」のセクションでは、表の保存先の決定について説明しました。ここでは、データをマイクロ管理し、行や列の配置を決定する方法を取り上げます。ディスク上で 1つ1つのバイトが占めるセクターの制御を試みることは、DB2よりも効果の低い選択をするという危険性をはらんでいます。DB2 が認識し得ないことをユーザーが知っていれば、パフォーマンスまたはスペース利用を最適化できる可能性があります。たとえば、DB2 には範囲の区分化機能はありません。その代わり、クラスター・マシン環境で (または大規模 SMP 上の複数の論理区画により) すべての区画で行がハッシュされ、データの均等分散が保証されます。これは随時照会には理想的です。ウェアハウスからロールイン/ロールアウトされるデータの場合、範囲の区分化が有利です。特に、最近の n 年、n か月、n 週間、n 日、n 時間、n 分、または n 秒のみを保持する必要がある場合、2000年7月のデータを削除したときに 2001年7 のデータを追加できる機能は強力です。これはディスク・スペースの節約に有効な方法です。しかし、7月のデータがすべてクラスター化されている場合、それを制御するハードウェアが酷使される可能性があります (銀行顧客が8の最初の週に7月の明細書を受け取ったときに 7月のデータを要求する照会の数を考えてみてください)。7月のデータでノードを酷使することは、データ・ウェアハウスを構築するために複数のマシンに投資した目的を無意味なものにしてしまいます。4つのプロセッサーが7月のデータの要求にかかりきりになっている一方で、残り11か月のデータに対して44のプロセッサーはほとんど何もしないでいるのなら、現在使用しているよりも沢山のハードウェアを購入できたはずです。1月の明細書について8月に電話問い合わせをしてくる顧客は一対何人いるでしょう。

範囲の区分化は、DBA にとっても追加の作業となる可能性があります。 http://www.tpc.org/tpch/results/h-ttperf.idc , の FDR (Full Disclosure Reports: 完全開示報告書) でベンチマークを比較すると、範囲の区分化によってデータベース管理システムでスキーマを作成するには、DB2のハッシュ区分化でスキーマを作成するのに必要な DDL行の数の約4倍が必要です。TPC-H 以前の TPC-Dでは、この差は 10:1というさらに大きなものでした。TPC-Dでは具体化されたビュー、要約表、および複数列の索引 (多数) を含むことができたため、この差にはほかの要因もありました。

DB2では、1つの区画に7月の全データを保管する場合、各月の表を作成し、UNIONを使用してすべてのデータを統合する必要がありました。これはEEEでは最適ではなく(EEE はシェアード・ナッシングであり、データが任意に分散している場合の方が効果的に機能します)、UNION は、ほかの方法と比べて応答セットの統合にはあまり効果的ではありません。DB2でハッシュ区分化を使用して全ノードにデータを分散し、受信データを利用して範囲の区分化の利点を実現する一方で、ハッシュ区分化の利点も維持する方がよりよい選択といえます。7月のデータは7月に受信するものです。すべての 7 月データを各ノードで隣接させておく ALTER TABLEステートメントの発行には最適なタイミングです。

ゆとりあるスペースの確保

このマジックを明かす前に、リレーショナル表の行にはもともと順序がないことを思い出してください。ユーザーとアプリケーション・プログラマーは、データを希望の順序に並べるには ORDER BYが必要であることを理解しなければなりません。月別 (または選択した範囲) のデータのクラスター化は偶然が幸いしたものです (2001年の行が 2000年の行より多いために追加で十分なスペースを予約していなかった場合は、再度このようになることはありません)。また、ここでリレーショナル表の列にもユニークな順序はないということを改めて述べておきます。この原則を覆すのはこの記事の最後になります。

まず、範囲の選択から始めます。月を例にとってきたので、それを使用することにします。ウェアハウスでは13か月分のデータを維持します。2001年7月になると、2000年6月が置換されます。普通は 2001年7月のデータは2000年6月のデータよりも大きいものです。これは7月は6月よりも1日多いことのほか、通常、経済とともにビジネスが伸びること (また株式買い入れ選択権がある場合は、その速度が加速されること) が期待されるからです。成長率が15%で、2002年およびその後の年の複合成長率を心配する前に、表を再編成する機会があると仮定しましょう。将来の成長に備えてスペースを確保するため、各ページに 15% の空きスペースを予約した表を作成します。通常、これは挿入のためですが、ここではデータのロールインとロールアウトの際に 2000年6月の行を2001年7月の行で置換するためです。以下の例では、単一のノード表を使ってこれを示しています。表を作成した後、対象範囲について索引でもスペースを予約します。PCTFREEでは5%を確保することを指定しています。

            CREATE TABLE RECEIPTS
                           (RECEIPT_DATE DATE NOT NULL, CUST_NUM INT NOT NULL,
                           RECEIPT_KEY TIMESTAMP NOT NULL, AMOUNT DEC(10,2),
                             PRIMARY KEY(CUST_NUM, RECEIPT_KEY))
                             PARTITIONING KEY (CUST_NUM, RECEIPT_KEY)

            CREATE INDEX DATE_IND ON RECEIPTS 
                         (RECEIPT_DATE) PCTFREE 15

この後、データが月ごとに挿入されます。

           INSERT INTO RECEIPTS VALUES ('2000-06-06',1,CURRENT TIMESTAMP,1)
           
.
           INSERT INTO RECEIPTS VALUES ('2001-06-16',40,CURRENT TIMESTAMP,33)

2001年7月のデータを受信すると、2000年6月のデータが削除されます。

          DELETE FROM RECEIPTS 
                      WHERE MONTH(RECEIPT_DATE)=6 
                      AND YEAR(RECEIPT_DATE)=2000

ここから2001年7月のデータの挿入を開始できます。

          INSERT INTO RECEIPTS VALUES ('2001-07-01',1,CURRENT TIMESTAMP,1)

上書きされる月 (2000年6月) のデータよりも多くのデータが 2001年7月にある場合、PCTFREE値を変更する必要があります。CREATE INDEXで初期のPCTFREEが指定されていますが、DB2 には ALTER INDEX ステートメントがないことに注意してください。CREATE INDEXで初期のPCTFREEを設定しますが、その後はALTER TABLEで調整します。

          ALTER TABLE RECEIPTS PCTFREE 10

または

          ALTER TABLE RECEIPTS PCTFREE 0

上記の例は極端に単純です。(RECEIPTS がどの区画に分散しているかを指定する) nodegroupの定義や、月次データがバッチでロードされた場合のロードの処理方法などはまだ取り上げていません。またクラスター索引も省いているほか、冗長データを保存しています (タイム・スタンプは RECEIPT_DATE列のスーパーセットです)。なぜこれだけ苦労する必要があるのでしょうか。それは、どの月をとっても、特定の月の全データが各ノード内のディスク上で隣接していても、その月の全データは区分化キー (CUST_NUM、RECEIPT_KEY) にハッシュ・キーを使用してすべてのノードに均等に分散されているためです。その月について照会する列 (RECEIPT_DATE) は、区分化キーの一部ではないことに注意してください。照会で2001年7月の行を求めると、各ノードによって同じ数の行が提供されます (したがって、すべてのハードウェアが使用され、データの分散により最大限の恩恵を享受できます) が、各ノード内では 2001年7月の行はディスク上で隣接しています。それらはバッファー・プールに入り、おそらく2001年8月末までメモリーに留まるため、顧客が7月の明細書に関して電話で質問をする際、照会が加速されます。7月の行がディスク上で隣接していることから、I/O が加速される可能性があるため、7月の明細書の印刷と照会も速くなるはずです。最後に、2000年6月の行が古くなって削除されたことによって空いたスペースに 2001年7月の行を入れることで、スペースを節約しました。くどいようですが、索引で PCTFREE を使って空きスペースを予約したので 2001年7月のデータは 2000年6月のデータよりも15% 大きくても差し支えありません。PCTFREE を低い値に変更するように表を変更することにより。この空きスペースに行を入れることができます。

急いてはことをし損ずる

上記の例は、INSERT を実施する際に表を走査し、空きスロットに新しい行を入れるDB2の機能を利用しています。この場合、6月分を削除すると、DB2は 2001年7月のデータを挿入する際、空になったそのスロットを見つけます。これにより、INSERT は遅くなりますが、SELECT は速くなります。ではその反対の条件、すなわち INSERT は速いほうがいいが、データに対する SELECTステートメントはあまりなさそうな場合 (そしてディスク・スペースはどうでもいい場合) です。前述の銀行の例を続けると、データ・ウェアハウスは13か月分のオンライン・データを維持しますが、銀行は 2000年6月のデータを実際には削除しません。監査担当者は、7年も10年も前に戻り、あなたが道で拾って銀行口座に預けた100ドルをなぜ報告しなかったのかを尋ねるかもしれません。要求の99%は最近13か月に関するものであるため、アプリケーションは次のようにして古くて遅いディスク上の表スペースに古いデータのための表を作成します。

CREATE TABLE OLD_RECEIPTS LIKE RECEIPTS IN SLOW_DISK_TBSP

2000年6月の行を削除する前に、副選択ステートメントとともにINSERTを使用して、それらの行をOLD_RECEIPTS表に移します。

	INSERT INTO OLD_RECEIPTS 
                          SELECT * FROM RECEIPTS 
                                       WHERE MONTH(RECEIPT_DATE)=6 
                                        AND YEAR(RECEIPT_DATE)=2000

これで2000年6月の行を削除できます。

	DELETE FROM RECEIPTS 
                               WHERE MONTH(RECEIPT_DATE)=6 
                               AND YEAR(RECEIPT_DATE)=2000

このシナリオでは、表スペースSLOW_DISK_TBSPによって使用されるデバイスのためにディスク・スペースを節約することを心配する必要はないかもしれません。この表にデータを移したところなので、これに対する照会は1%以下であることを考えると、次のようにいくつかの点は正しいと思われます。

  1. 銀行が営業している限り表は増大を続ける。
  2. 行はこの表に挿入されるだけで削除や更新はされないため、新しい行を挿入する際にDB2で空きスロットを検索しても意味がない。13か月以上も前に発生した取引レコードを銀行が変更することはどれだけあるでしょうか。

以下のようにAPPEND ONを切り替えるように表を変更することにより、INSERTの実行時にDB2が空きスロットを検索しないように指定することもできたはずです。

ALTER TABLE OLD_RECEIPTS APPEND ON

これにより、INSERTの実行が速くなります。銀行が建設的な会計処理をすばやく実行する必要があって、1990年代後半に関して「発見された」多数のINSERT、UPDATE、DELETEなどをOLD-RECEIPT表に適用する場合、APPENDをオフにすることができます。

第5列
ディスク上の行の並べ方に関するヒントを学びましたが、ユーザーにとって順序が大事である場合、それを ORDER BY で指定する必要があることを忘れないでください。ORDER BY による指定がなければ、DB2 では特定の順序による行の表示は保証されません。ORDER BY を指定しない限り、保守または新規リリースの結果発生したアクセス・プランの変更、または個々のプロセッサーがコーディネーター・ノードに行を転送する速度の変化によって、どのような結果セットの順序でも任意になってしまいます。列は同じようであっても異なるものです。SELECT ステートメントを使用して希望の列順序を指定します。SELECT * によって、表の作成時に指定された順序に列が編成されます。列の順序は重要なのでしょうか。おそらくそうでしょう。次の情報は Windows、Unix、OS/2 上での DB2 にのみ適用することに注意してください。その他のプラットフォームでの列の扱いは異なります。また、以下で取り上げる情報は将来の DB2 リリースで変更される可能性もあります (ただし、変更された場合、DB2 バージョン 7.2 以前で作成された表を新しいフォーマットに移行するためには、大規模なエンジニアリング作業が必要になります)。

SELECT 操作を加速するために、表の作成時に列の順序を指定する最適な方法はありません。しかし、作成時にそれがわかっている場合は、最も頻繁に更新される列を最初にリストすると効果的です。行の UPDATE が実行されると、DB2 はその結果をログに書き込み、即座にまたは最終的に (通常はバッファー・プールが更新されるときに) 行を保管するディスクにそれを書き込む必要があります。ログには行全体は書き込みません。変更のある列のみ書き込む必要があります。ログに書き込まれるのは行の最初の列です。そしてその後、変更のあった最後の列に DB2 が到達するまですべての行が対象になります。顧客の社会保障番号が絶対に変わることがない場合は、行の最後の方にそれを入れます。口座残高などのように常に変化しているものは、行の初めの方に入れます。また、住所のようにときどき変更されるものは、口座残高と社会保障番号の間にくるようにします。 ディスクでの項目の配置を見てみましょう。固定長の列のみで表を作成した場合、CREATEステートメントで表が指定されているのとまったく同じように配置されます。

           CREATE TABLE TESTORD (COL1 INT, COL2 CHAR(5), COL3 DEC(10,2), COL4 FLOAT)
図1
図1
図1

表にVARCHAR のように可変長の列がある場合でも、それらの列は CREATE TABLEで指定された順序になりますが、可変データ自体は行の最後になります。

           CREATE TABLE TESTORD (COL1 INT, COL2 VARCHAR(5), COL3 DEC(10,2))
図2
図2
図2

表に長形式フィールドがある場合、それは各行と並んで配置されません。行幅はページ・サイズ (4K〜32K) によって制約されるため、行には長形式フィールドへのポインターしかありません。ポインターは行とは別にデータベース・ページに配置されます。

          CREATE TABLE TESTORD (COL1 INT, COL2 CLOB(100 K), COL3 DEC(10,2))
図3
図3
図3

ワンストップ・ショッピング

索引ではデータに冗長性をもたせますが、ユーザーからは見えないようになっています (表の更新時にユーザーは索引の更新を心配する必要はありません。これはDB2の仕事です)。DB2はほかの多数のデータベース管理システムに比べて、索引に大きく依存します。これは主に、DB2が高度なオプティマイザーを備えているためです。「ワンストップ・ショッピング」は、データベースの世界では索引のみのアクセスとして知られています。SELECTで必要なすべてのデータが索引にあれば、DB2は索引を読み取るだけで済みます。主キーのNAMEに関する次の表とその索引を考えてみましょう。

                 CREATE TABLE ADDRESS
                                        (NAME CHAR(20) not null,
                                        STREET CHAR(20),
                                        CITYPROV CHAR(20),
                                        POSTCODE CHAR(7),
                                        HOMEPHONE CHAR(12),
                                        WORKPHONE CHAR(12),
                                        NOTES CHAR(20))
 
	   CREATE UNIQUE INDEX NAME_INDX ON ADDRESS (NAME)

以下を発行した場合、DB2は索引のみを走査して照会結果を収集します。

SELECT NAME FROM ADDRESS

または

SELECT NAME FROM ADDRESS WHERE NAME = 'Adamache, Blair'

また、以下を発行した場合、DB2は表を走査します。索引は役に立ちません。

SELECT NAME, WORKPHONE FROM ADDRESS

コマンド・センターから上記のコマンドのすべてを発行し、「アクセス・プランの作成」アイコンを使用してDB2オプティマイザーが使用したデータのパスを確認したりすることにより、これらのアクセス・パスをテストできます。上記の3つの SELECT はすべてワンストップ・ショッピングを実行します。照会は表または索引のいずれかだけで処理できます。オプティマイザーは索引を使用するが、その他の列を選択するためには表からの読み取りも必要な場合はどうでしょうか。この場合の SELECT では索引の走査と表の読み取りの両方が必要になります。

SELECT NAME, WORKPHONE FROM ADDRESS WHERE NAME = 'Adamache, Blair'

これが共通のアクセス方法である場合 (通常、電話番号が必要な場合、名前で検索を開始するものです)、索引に追加の列を含めるようにDB2に指示することができます。WORKPHONE は、主キーの一部にはなりません。索引のみのアクセスでより多くの照会を処理できるように、索引に含められるだけです。単一列の索引を排除することから開始しましょう。

DROP INDEX NAME_INDX

ここで索引を再作成し、ユーザーが通常望む追加の列 (複数可) を含めます。

	  CREATE UNIQUE INDEX NAME_INDX ON ADDRESS (NAME) 
                               INCLUDE (WORKPHONE, HOMEPHONE)

追加の列が多くなるほど、UPDATE と INSERT にかかる時間は長くなることを忘れないでください。含めた列は、表と索引の両方で変更しなければならないからです。

INCLUDE で追加列を指定した索引では、次の照会を索引のみのアクセスで実行できます。

	  SELECT NAME, WORKPHONE FROM ADDRESS WHERE NAME = 'Adamache, Blair'

結論

行と列の配置を決定するためのヒントを紹介してきましたが、人間の仕事はDBA(データベース管理者) であり、DB2の仕事はデータベース・マネージャーです。たいていの場合、DB2はスキーマやそれに対して作成された索引に基づき正しい決定を下します。ここでは、ハードウェア投資を回収するためにDB2 EEEのシェアード・ナッシング・アーキテクチャーを利用することを常に強調しました。これはソフトウェアについてもいえることです。ハードウェアに対して支払い、DB2の最適化プログラム、データ・マネージャー、およびそのリレーショナル・エンジンなどのソフトウェアに対しても支払ったはずです。この記事で紹介した技法のいくつかは、データベース・アプリケーションで重要な表に対して今後実施してみる価値があります。データベースで作成されたすべての表について、すべての技法を実施する必要はありません。それほど時間のある方は、DB2 のチューニング方法を他人に伝授するためDB2に関する記事や本を書いて生計を立てることができるでしょう。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Information Management
ArticleID=323071
ArticleTitle=DB2 ストレージあれこれ
publish-date=11262004