| Oracle Database パフォーマンス・チューニング・ガイド 10gリリース2(10.2) B19207-02 |
|
この章では、索引およびクラスタを使用してパフォーマンスを強化できる、または低下させるデータ・アクセス方法の概要を説明します。
この章には次の項があります。
この項では、次の項目について説明します。
問合せの最適化は、問合せ実行におけるあまり有効ではない索引の使用を避けるために役立ちますが、SQLエンジンは、表に対して定義されている索引が使用されているかどうかにかかわらず、継続的にすべての索引をメンテナンスします。書込み集中型アプリケーションでは、索引のメンテナンスにCPUとI/Oリソースが大量に必要となる場合があります。したがって、必要がなければ索引を作成しないでください。
最適なパフォーマンスを保つために、アプリケーションで使用していない索引を削除してください。使用されていない索引は、ALTER INDEX MONITORING USAGE機能を典型的な負荷を一定期間かけた後に使用することで検出できます。この監視機能は、索引が使用されたかどうかを記録します。使用されていない索引が検出された場合は、削除してください。サンプリングした負荷以外の負荷で使用されている索引を削除しないように、典型的な負荷を監視していることを確認してください。
また、アプリケーション内では、文の実行計画の調査ですぐには明らかにならない索引の使用方法もあります。その例が、共有ロックが子表上に取り出されないようにする親表上の外部キー索引です。
また、新しい索引を作成してSQL文をチューニングするかどうかを決める場合、オプティマイザがアプリケーションの実行時にこれらの索引を使用するかどうかを判断するために、EXPLAIN PLAN文を使用することもできます。新しい索引を作成して現在解析中の文をチューニングする場合は、Oracleはその文を無効にします。
その文が次に解析されるとき、オプティマイザは、新しい索引を使用する可能性のある新しい実行計画を自動的に選択します。新しい索引をリモート・データベース上に作成して分散型の文をチューニングする場合は、その文が次に解析されるとき、オプティマイザがこれらの索引について検討します。
索引を作成してある文をチューニングした場合、他の文の実行計画に対するオプティマイザの選択に影響を及ぼす場合があるので注意してください。たとえば、ある文によって使用される索引を作成した場合、オプティマイザは、アプリケーションの他の文に対しても、その索引の使用を選択する場合があります。このため、最初にチューニング対象と判断した文をチューニングした後、アプリケーションのパフォーマンスおよび実行計画を再検査し、SQLトレース機能を利用します。
SQLアクセス・アドバイザは、どの索引が必要であるかを手動で判別する作業に対する代替機能です。 このアドバイザをOracle Enterprise Managerから起動するか、DBMS_ADVISORパッケージAPIを介して実行すると、索引セットを推奨します。SQLアクセス・アドバイザはワークロードの使用を推奨するか、または指定のスキーマに関する仮定的なワークロードを生成します。SQLキャッシュの現在の内容、ユーザー定義のSQL文セットまたはSQLチューニング・セットなど、様々なワークロード・ソースが使用可能です。SQLアクセス・アドバイザにより指定のワークロードに関して推奨事項のセットを生成され、その中から実装する索引を選択できます。実装スクリプトが用意されており、手動で実行するか、またはOracle Enterprise Managerを介して自動的に実行できます。SQLアクセス・アドバイザの詳細は、「DBMS_ADVISORパッケージのSQLアクセス・アドバイザの概要」を参照してください。
キーは、索引を付ける列または式です。次のガイドラインに従って、索引を付けるキーを選択します。
WHERE句で頻繁に使用されるキーに索引を付けることを検討します。
選択性の低い列への索引付けは、データ配分が偏っているために、1つまたは2つの値がその他の値よりはるかに使用頻度が低い場合に便利です。
UPDATE文および索引付きの表を修正するINSERT文とDELETE文では、索引がない場合よりも、処理に長い時間が必要となります。このようなSQL文は、表のデータのみでなく、索引のデータも修正する必要があります。また、取消しと再実行も追加的に生成されます。
WHERE句のみに指定されるキーには索引を付けません。索引付きのキーにMINやMAX以外の関数や演算子を使用するWHERE句は、ファンクション索引を除く索引を使用するアクセス・パスを選択しません。
INSERT文およびUPDATE文、DELETE文が親表と子表をアクセスする場合、参照整合性制約の外部キーに索引を付けることを検討します。このような索引を使用すると、子表を共有ロックせずに親表でUPDATEおよびDELETEを実行できます。
INSERT、UPDATE、DELETEのパフォーマンス損失および索引を格納するために必要となる領域の使用に見合う価値があるかどうか検討してください。SQL文の処理時間を索引の有無によって実際に比較することをお薦めします。SQLトレース機能で処理時間を測定できます。 コンポジット索引には複数のキー列が含まれています。コンポジット索引には、次のような単一列索引を上回る利点があります。
場合によっては、それぞれの選択性が劣る複数の列や式を組み合せてコンポジット索引にすると、より高い選択性を得ることができます。
問合せによって選択される列がすべてコンポジット索引に含まれている場合、Oracleは、表にアクセスすることなく、索引からこれらの値を戻すことができます。
SQL文にコンポジット索引の先頭部分を利用する条件が含まれていれば、その文はコンポジット索引に関係するアクセス・パスを使用します。
索引の先頭部分とは、その索引を作成したCREATE INDEX文で列リストの先頭から連続的に指定された1つ以上の列の組合せのことです。次のCREATE INDEX文を例とします。
CREATE INDEX comp_ind ON table1(x, y, z);
コンポジット索引を構成するキーを選択するために、次のガイドラインに従ってください。
WHERE句の条件で、頻繁にAND演算子で結合して使用されるキー・セットに対して、コンポジット索引を作成することを検討します。特に結合したときの選択性が個々のキーの選択性よりも優れている場合、コンポジット索引を作成してください。
もちろん、索引を作成するときの、一般的なパフォーマンスの利点およびトレードオフに関する前述のガイドラインを検討してください。
コンポジット索引内でのキーの順序を指定するために次のガイドラインに従ってください。
WHERE句で使用されるキーが先頭部分を構成するように、索引を作成してください。
WHERE句で使用される頻度が高い場合には、頻繁に選択されるキーが先頭部分を構成するように索引を作成し、これらのキーのみを使用する文が索引を使用できるようにしてください。
WHERE句で使用される頻度が同程度で、そのキーの1つでデータが物理的に順序付けられている場合には、そのキーをコンポジット索引の先頭にしてください。
索引を作成しても、単に索引が存在するのみでは、オプティマイザはその索引を使用するアクセス・パスを選択できません。オプティマイザは、SQL文にアクセス・パスを使用可能にする構造が含まれている場合にかぎり、そのようなアクセス・パスを選択できます。索引アクセス・パスを使用するというオプションを問合せオプティマイザで可能にするには、文が索引アクセス・パスを使用可能にする構文になっていることを確認してください。
場合によっては、既存の索引を使用するアクセス・パスをSQL文で使用しないことも可能です。索引の選択性があまり優れておらず、全表スキャンの方が効率的であることがわかっている場合がそうです。そのような索引アクセス・パスを使用可能にする条件が文に含まれている場合は、次に示す方法の1つを使用して、オプティマイザに全表スキャンを使用するように強制できます。
NO_INDEXヒントを使用して特定索引の使用を禁止にし、問合せオプティマイザに最大限の柔軟性を持たせることができます。
FULLヒントを使用し、オプティマイザに対して索引スキャンのかわりに全表スキャンを選択するように指示します。
INDEXヒントまたはINDEX_COMBINEヒントを使用し、オプティマイザに、ある索引(またはリストされている索引セット)を別の索引(または索引セット)のかわりに使用するように指示します。 パラレル実行は、索引を効果的に利用します。このオプションはパラレル索引レンジ・スキャンは実行しませんが、ネステッド・ループ結合を実行するためにパラレル索引参照を実行します。索引の選択性が高い(各索引エントリの行数が少ない)場合は、パラレル表スキャンよりも順次索引参照を使用することをお薦めします。
索引を縮小し分断化された領域を最小化するため、または索引の記憶特性を変更するために索引を再作成する場合があります。既存の索引のサブセットとなる新しい索引を作成するとき、または既存の索引を新しい記憶特性で再構築するとき、Oracleは、実表ではなく既存の索引を使用して索引作成のパフォーマンスを向上させる場合があります。
ただし、既存の索引よりも実表を使用した方が効果的な場合もあります。多くのDMLが実行された表の索引を考えてみてください。DMLのために索引のサイズが大きくなり、各ブロックが50%以下しか満たされなくなる場合があります。索引が表のほとんどの列を参照している場合、索引が表よりも大きくなりかねません。その場合は、索引よりも実表を使用した方が、索引の再作成が速くできます。
ALTER INDEX ...REBUILD文は、既存の索引を再編成または縮小するため、または既存の索引の記憶特性を変更するために使用します。REBUILD文は、新しい索引の基礎として既存の索引を使用します。STORAGE(エクステントの割当て用)、TABLESPACE(索引を新しい表領域に移動する)およびINITRANS(エントリの最初の数を変更する)などのすべての索引記憶用の文がサポートされています。
ALTER INDEX ...REBUILDは、高速全スキャン機能を使用するので、通常は索引を削除して再作成するよりも高速です。この文は、マルチブロックI/Oを使用して索引ブロックをすべて読み込んでから、ブランチ・ブロックを廃棄します。さらに、このアプローチには、再作成の実行中の問合せには、旧索引を利用できるという利点があります。
COALESCEオプションを持つALTER INDEX文を使用して索引のリーフ・ブロックを結合できます。このオプションでは、索引のリーフ・レベルを結合して空きブロックにし、再利用できます。また、索引をオンラインで再作成することもできます。
UNIQUE制約、またはPRIMARY KEY制約の一意性の側面に関して、一意性を規定するために、表の既存の一意でない索引を使用できます。このアプローチの利点は、制約が使用禁止にされているときでも索引が使用可能であり、妥当であるということです。したがって、使用禁止にされているUNIQUE制約またはPRIMARY KEY制約を使用可能にするために、その制約に対応付けられているUNIQUE索引を再作成する必要はありません。これにより、大規模表で操作を使用可能にする際に時間を大幅に節約できます。
さらに、一意でない索引を使用して一意性を規定すると、索引の重複を排除できます。主キー列がすでにコンポジット索引の同一キーとして組み込まれている場合、その列に対する一意索引は不要です。Oracleでは、制約を使用可能または規定するときに、既存の索引を使用できます。索引を複製しないので、領域を大幅に節約できます。ただし、既存の索引がパーティション化されている場合は、索引のパーティション・キーもUNIQUEキーのサブセットである必要があります。サブセットでなければ、Oracleはさらに一意索引を追加作成し、制約を規定します。
ENABLE NOVALIDATE制約は、新しいデータのENABLE VALIDATE制約と同じように動作します。制約をENABLE NOVALIDATE状態にすることは、表に入力された新規データが制約に準拠する必要があることを意味します。既存のデータはチェックされません。制約をENABLE NOVALIDATE状態にすることにより、表をロックしないで制約を使用可能にできます。
制約を使用禁止から使用可能に変更する場合、表をロックする必要があります。使用可能化操作の間に表の操作が制約に準拠していることを保証する機能がないため、新たにDML、問合せまたはDDLを実行できません。ENABLE NOVALIDATE状態では、制約に違反する操作は表に対して実行されません。
表のパラレル一貫読込み問合せによってENABLE NOVALIDATE制約を検査済にすることで、制約に違反するデータがあるかどうかを判断できます。ロックは実行されず、使用可能化操作は表に対する読込み機能または書込み機能をブロックしません。さらに、ENABLE NOVALIDATE制約はパラレルで検査済にできます。複数の制約を同時に検査済にし、パラレル問合せを使用して各制約の妥当性チェックを実行できます。
制約と索引を持つ表を作成するアプローチは次のとおりです。
NOT NULL制約には名前を付けなくても構いませんが、検査済使用可能で作成してください。その他の制約(CHECK、UNIQUE、PRIMARY KEYおよびFOREIGN KEY)にはすべて名前を付け、使用禁止で作成します。
ALTER TABLE文を使用して、すべての制約を検査します。これは、外部キーの前に主キーに対して行ってください。次に例を示します。
CREATE TABLE t (a NUMBER CONSTRAINT apk PRIMARY KEY DISABLE, b NUMBER NOT NULL); CREATE TABLE x (c NUMBER CONSTRAINT afk REFERENCES t DISABLE);
ここで、インポートまたは高速ローダーを使用してデータを表tにロードします。
CREATE UNIQUE INDEX tai ON t (a); CREATE INDEX tci ON x (c); ALTER TABLE t MODIFY CONSTRAINT apk ENABLE NOVALIDATE; ALTER TABLE x MODIFY CONSTRAINT afk ENABLE NOVALIDATE;
この時点で、ユーザーは、表tでINSERT、UPDATE、DELETEおよびSELECTを実行できます。
ALTER TABLE t ENABLE CONSTRAINT apk; ALTER TABLE x ENABLE CONSTRAINT afk;
これで、制約はENABLE VALIDATEになりました。
ファンクション索引には、関数(たとえば、UPPER関数)で変換される列、または式(たとえば、col1 + col2)に含まれている列が含まれています。ファンクション索引により、索引で計算集中型の式を保存できます。
変換された列または式でファンクション索引を定義すると、その関数または式をWHERE句またはORDER BY句で使用するとき、その索引を使用してデータを戻すことができます。これにより、Oracleは、SELECT文およびDELETE文を処理する際に式の値の計算をバイパスできます。したがって、ファンクション索引は、頻繁に実行されるSQL文のWHERE句またはORDER BY句の中に変換列(または式の中の列)が含まれているときに有益です。
Oracleでは、降順の索引は、ファンクション索引として処理されます。DESCのマークのある列は、降順でソートされます。
たとえば、UPPER(column_name)キーワードまたはLOWER(column_name)キーワードで定義されたファンクション索引を使用すると、大小文字を区別しない検索ができます。次の文で索引を作成します。
CREATE INDEX uppercase_idx ON employees (UPPER(last_name));
これを使用すると、次のような問合せの処理が容易になります。
SELECT * FROM employees WHERE UPPER(last_name) = 'MARKSON';
パーティション表と同様に、パーティション索引を使用すると、管理可能性、可用性、パフォーマンスおよび拡張性が向上します。パーティション索引は、個別にパーティション化するか(グローバル索引)、または表のパーティション・メソッドに自動的にリンクできます(ローカル索引)。
Oracleでは、レンジ・パーティション化およびハッシュ・パーティション化されたグローバル索引をどちらもサポートしています。レンジ・パーティション化されたグローバル索引では、各索引パーティションに、パーティション・バウンドで定義された値が含まれます。ハッシュ・パーティション化されたグローバル索引では、各パーティションに、Oracleのハッシュ関数により決定された値が含まれます。
マルチユーザーのOLTP環境で、索引内の少数のリーフ・ブロックに競合が多い場合、ハッシュ・メソッドにより索引のパフォーマンスが向上します。OLTPアプリケーションによっては、索引の右端にのみ索引が挿入される場合があります。これは、単調に増える列について索引が定義されている場合に行われます。このような場合、索引ページ、バッファ、更新のラッチ、および追加索引メンテナンス・アクティビティの競合により、索引の右端がホット・スポットとなり、パフォーマンスが低下します。
ハッシュ・パーティション化されたグローバル索引では、索引エントリはパーティション・キーおよびパーティション数に基づいて異なるパーティションにハッシュされます。これにより、定義済のパーティション数全体に競合が拡散され、スループットが向上します。ハッシュ・パーティション化されたグローバル索引を使用すると、バッファ・ラッチの競合が複数のパーティションにわたって拡散されるため、大規模PDMLとして大きなファクト表に実行されるTPC-Hリフレッシュ関数には有効です。
ハッシュ・パーティション化では、索引エントリはOracleで生成されたハッシュ値に基づいて特定の索引パーティションにマップされます。ハッシュ・パーティション化されたグローバル索引を作成するための構文は、ハッシュ・パーティション表と非常によく似ています。索引パーティション・キーについての等価述語およびIN述語を伴う問合せでは、グローバル・ハッシュ・パーティション索引を効率的に使用して問合せにすばやく回答できます。
索引構成表は、表のデータが、対応付けられた索引に保持されるという点で普通の表とは異なります。新しい行の追加、行の更新、行の削除など、表データを変更すると、索引のみが更新されます。データ行は索引に格納されるため、索引構成表では完全一致、範囲検索またはその両方を含む問合せの表データに対するさらに高速なキー・ベースのアクセスが可能になります。
グローバル・ハッシュ・パーティション索引は索引構成表でサポートされており、マルチユーザーのOLTP環境でパフォーマンスが向上します。
ビットマップ索引は、次のすべての特性を持つ問合せのパフォーマンスを大幅に向上できます。
WHERE句に複数含まれています。
複数のビットマップ索引を使用して、単独の表に対する条件を評価できます。このため、ビットマップ索引は、長いWHERE句を含む複合非定型問合せにとって非常に有効です。ビットマップ索引は、集合問合せでもスター・スキーマでの結合の最適化でも最適なパフォーマンスを提供します。
単一表のビットマップ索引に加えて、ビットマップ結合索引を作成できます。このビットマップ結合索引は、複数の表を結合するためのビットマップ索引です。ビットマップ結合索引は、事前の制限事項の実行により結合される必要のあるデータ量を削減するためにスペースを節約するよい方法です。ビットマップ結合索引は、表の列の値ごとに、別の表の対応する行のROWIDを格納します。データ・ウェアハウス環境では、結合条件は、ディメンション表の主キー列、およびファクト表の外部キー列との間の等価内部結合です。
ビットマップ結合索引は、マテリアライズド結合ビューより格納の効率がはるかによく、事前に結合をマテリアライズする方法の代替手段です。これは、マテリアライズド結合ビューがファクト表のROWIDを圧縮しないためです。
ドメイン索引は、ユーザー定義の索引タイプで指定された索引作成論理で作成されます。索引タイプを使用すると、特定の演算子の述部に合うデータに効率よくアクセスできます。通常、ユーザー定義の索引タイプは、Spatialオプションと同様Oracleのオプションの一部です。たとえば、SpatialIndextypeを使用すると、ある条件ボックスにオーバーラップするSpatialデータを効率よく取り出せます。
ドメイン索引の作成と保守で指定できるパラメータは、カートリッジによって異なります。同様に、ドメイン索引のパフォーマンスと記憶域の特性は、カートリッジ固有のマニュアルを参照してください。
次の情報は、適切なカートリッジ・マニュアルを参照してください。
クラスタとは、物理的にまとめて格納される1つ以上の表のグループです。それらの表は、共通の列を共有しており、通常、一緒に使用されるため、まとめて格納されます。関連する行が物理的にまとめて格納されているため、ディスク・アクセス時間が短縮されます。
クラスタを作成するには、CREATE CLUSTERコマンドを使用します。
表をクラスタ化するかどうかを判断するために、次のガイドラインに従ってください。
アプリケーションのニーズに応じて、クラスタの長所と短所を検討してください。たとえば、結合文のパフォーマンス向上が、クラスタ・キー値を修正する文のパフォーマンス低下を上回る場合もあります。表をクラスタ化した場合と別々に格納した場合について実験して、処理時間を比較してください。
ハッシュ・クラスタは、ハッシュ関数をそれぞれの行のクラスタ・キー値に適用することによって、表データをグループ分けします。同じクラスタ・キー値を持つすべての行が、ディスク上にまとめて格納されます。アプリケーションのニーズに応じて、ハッシュ・クラスタの長所と短所を検討してください。特定の表をハッシュ・クラスタに格納する場合と、索引付きで単独に格納する場合を実験して、処理時間を比較してください。
ハッシュ・クラスタを使用する場合を判断するために、次のガイドラインに従ってください。
WHERE句に含まれる場合、WHERE句を持つSQL文により頻繁にアクセスされる表を格納するために、ハッシュ・クラスタが使用されます。この列または列の組合せをクラスタ・キーとして指定します。
前述の考慮事項に基づいてハッシングが適切であるかぎり、他の表と頻繁に結合されるかどうかにかかわらず、単一の表をハッシュ・クラスタに格納することは有益です。
|
![]() Copyright © 2000, 2008, Oracle Corporation. All Rights Reserved. |
|