この記事では、インデックスによってクエリのパフォーマンスがどのように向上するかを見ていきます。
はじめに
Oracleおよびその他のデータベースのインデックスは、他のテーブルのデータへの参照を格納するオブジェクトです。これらは、クエリのパフォーマンスを向上させるために使用されます。ほとんどの場合、SELECTステートメントです。
これらは「特効薬」ではありません。SELECTステートメントのパフォーマンスの問題を常に解決できるとは限りません。しかし、彼らは確かに助けることができます。
特定の例でこれを考えてみましょう。
例
この例では、ID、名、姓、最大クレジット値、作成日値、および使用しないその他の列を含むCustomerという単一のテーブルを使用します。
SELECT customer_id,first_name,last_name, max_credit, created_date FROM customer;
これが表のサンプルです。
[テーブルID=38 /]
ここで、次のものを見つけます。
- 最初の顧客と同じ日にテーブルに追加されたクライアントは誰ですか
- last_nameで昇順でフィルタリングされたクライアント
- 顧客ID、名、姓、最大クレジット、作成日を表示します
これを行うには、次のクエリを作成します。
SELECT customer_id, first_name, last_name, max_credit, created_date FROM customer WHERE created_date = ( SELECT MIN(created_date) FROM customer ) ORDER BY last_name;
出力は次のようになります:
[テーブルID=39 /]
必要なデータが表示されます。
インデックスが適用される前のパフォーマンス
それでは、このクエリの説明プランを見てみましょう。これは、SELECTステートメントに対してEXPLAIN PLAN FORを実行し、次のコマンドを実行することで取得しました。
SELECT * FROM TABLE(dbms_xplan.display);
IDE内のプランの説明機能を使用しても同様の出力結果を得ることができます。
サブクエリと外部クエリの2つのポイントでテーブルアクセスフルを実行していることがわかります。これは、使用するテーブルにインデックスがないためです。
コストは2934です。実行すると、クエリは1.9秒で785行をフェッチしました。すぐに思えるかもしれませんが、これは改善できる例にすぎません。実際のシステムでのクエリには、はるかに長い時間がかかる場合があります。
このクエリのパフォーマンスを向上させる1つの方法は、created_date列にインデックスを追加することです。この列は、外部クエリのWHERE句と内部クエリのMIN関数の両方で使用されます。
インデックスの追加
このテーブルにインデックスを追加して、クエリのパフォーマンスを向上させることができます。このインデックスはcreated_date列に格納されるため、コードは次のようになります。
CREATE INDEX idx_cust_cdate ON customer (created_date);
現在、インデックスはこの列にのみ作成されます。クエリのパフォーマンスが向上するはずですが、最初に確認する必要があります。
b-treeインデックスを作成しました。これは、おそらくこの列に必要なすべてです。間もなく説明プランで確認します。使用するインデックスの種類を知る方法や、その他の多くの貴重な情報など、Oracleインデックスに関するガイドを作成しました。
インデックス作成後のパフォーマンス追加
このクエリでExplainプランを再実行しましょう。
最後のステップでインデックスが使用されていることがわかります。これは、作成したばかりのidx_cust_cdateインデックスを使用してフルスキャンが実行されたことを示しています。
また、1472の全体的なコストを示し、0.9秒で785レコードをフェッチします。
実行時間はわずかに改善されましたが(1.9秒から0.9秒)、この小さなデータセットにインデックスを追加するだけで約50%の改善になります。
前述のように、実際のクエリはこれよりも複雑になり、実行に時間がかかります。ただし、これは、インデックスによってクエリプランとクエリランタイムを改善する方法の例です。