8

Oracleがこれらをパフォーマンスチューニングなどに使用していることを説明するドキュメントを見つけましたが、実際に何をするのかよくわかりませんでした。

誰かが非常に基本的な例で簡単な言葉でそれを私に説明できますか?

4

1 に答える 1

52

Oracleを含むほとんどのエンタープライズデータベースは、コストベースのオプティマイザを使用して、特定のSQLステートメントに適切なクエリプランを決定します。これは、オプティマイザーがデータに関する情報を使用して、ルールに依存するのではなく、クエリの実行方法を決定することを意味します(これは、古いルールベースのオプティマイザーが行ったことです)。

たとえば、単純なバグ追跡アプリケーションの表を想像してみてください

CREATE TABLE issues (
  issue_id number primary key,
  issue_text clob,
  issue_status varchar2(10)
);

CREATE INDEX idx_issue_status
    ON issues( issue_status );

私が大企業の場合、このテーブルには100万行ある可能性があります。これらのうち、100はissue_statusACTIVE、10,000はissue_statusQUEUED、989,900はCOMPLETEのステータスです。テーブルに対してクエリを実行して、アクティブな問題を見つけたい場合

SELECT *
  FROM issues
 WHERE issue_status = 'ACTIVE'

オプティマイザには選択肢があります。でインデックスを使用してissue_statusから、一致するインデックスの各行についてテーブルで単一行ルックアップを実行するか、テーブルでテーブルスキャンを実行することができissuesます。どのプランがより効率的かは、テーブルにあるデータによって異なります。Oracleがクエリがテーブル内のデータのごく一部を返すことを期待している場合は、インデックスを使用する方が効率的です。Oracleがクエリがテーブル内のデータのかなりの部分を返すことを期待している場合、テーブルスキャンの方が効率的です。

DBMS_STATS.GATHER_TABLE_STATSこれは、Oracleがこの決定を行うことを可能にする統計を収集するものです。これは、テーブルに約100万行あり、列に3つの異なる値がありissue_status、データが不均一に分散されていることをOracleに通知します。したがって、Oracleは、クエリにインデックスを使用して、すべてのアクティブな問題を見つけることを知っています。しかし、振り返ってすべてのクローズされた問題を探しようとすると、それも知っています

SELECT *
  FROM issues
 WHERE issue_status = 'CLOSED'

テーブルスキャンを実行する方が効率的です。

統計を収集すると、データ量とデータ分布の変化に応じてクエリプランを時間の経過とともに変更できます。課題トラッカーを最初にインストールすると、完了した課題はほとんどなく、アクティブな課題とキューされた課題が増えます。時間の経過とともに、完了した問題の数ははるかに急速に増加します。テーブル内の行数が増え、さまざまなステータスにある行の相対的な割合が変わると、クエリプランが変更されるため、理想的な世界では、常に可能な限り最も効率的なプランを取得できます。

于 2013-03-22T17:51:47.847 に答える