2

予期しない結果をもたらす非常に単純なクエリがあります。どこでトラブルシューティングを行うべきかについてのヒントは大歓迎です。

簡素化されたクエリは次のとおりです。

SELECT Obs.obsDate, 
       Obs.obsValue, 
       ObsHead.name
  FROM ml.Obs Obs 
  JOIN ml.ObsHead ObsHead ON ObsHead.hdId = Obs.hdId
 WHERE obs.hdId IN (53, 54)

これにより、クエリのコストは963になります。ただし、クエリを次のように変更すると:

SELECT Obs.obsDate, 
       Obs.obsValue, 
       ObsHead.name
  FROM ml.Obs Obs 
  JOIN ml.ObsHead ObsHead ON ObsHead.hdId = Obs.hdId
 WHERE ObsHead.name IN ('BP SYSTOLIC', 'BP DIASTOLIC')

同じデータが返されるはずですが、推定コストは17688まで跳ね上がります。ここでの問題はどこにある可能性が高いですか? ありがとう。

編集:クエリ プランによると、インデックスObsHead.Nameは範囲スキャンに使用され、ObsHead のテーブル アクセスのコストは 4 です。別のインデックスがObs.hdIdレンジ スキャンに使用されており、コストは 94 です。それは、テーブル間のネストされたループ結合です。 17K までジャンプします。

4

4 に答える 4

1

コストは、1 つのクエリの異なるプランを比較する場合にのみ役立ちます。異なるクエリを比較するのにはあまり役に立ちません。

計画を見て、実行するアクションの観点から比較する必要があります。

これらのクエリの実際のパフォーマンスは似ていると思いますが、最初のクエリがハッシュ結合を使用しているかどうかを知ることは興味深いでしょう。これは、obs一致するレコードの割合が重要な場合に役立つ可能性があります。

于 2010-03-11T02:33:36.797 に答える
1

既に述べたように、プランのコストは 2 つの異なるクエリを比較するためのものではなく、同じクエリの異なるパスを比較するためだけのものです。

これは推測にすぎませんが、この場合、プランのカーディナリティ フィールドの方が役立つ可能性があります。OBSHEAD のインデックスが一意ではなく、推定値を使用して統計が収集された場合、オプティマイザは、そのテーブルをクエリするときに予期される正確な行数を認識できない可能性があります。カーディナリティは、これが真であるかどうかを示します (理想的には、OBSHEAD のカーディナリティが 2 であることがわかります)。

別の提案は、OBS の統計を確認することです。頻繁に増加するテーブルである可能性が高いと思われます。この場合、1 月 28 日は統計を収集するのに十分な時間ではありません。このテーブルの監視がオンになっていると仮定すると、以下のクエリは、統計が古く、更新する必要があるかどうかを示します。

select owner, table_name, last_analyzed, stale_stats
from all_tab_statistics
where owner = 'ML' and table_name = 'OBS';

select owner, index_name, last_analyzed, stale_stats
from all_ind_statistics
where owner = 'ML' and table_name = 'OBS';
于 2010-03-12T22:27:27.423 に答える
1

オプティマイザによって提供されるコストは興味深いものですが、特に有用ではありません。クエリを比較するために私が見つけた最良の方法は、それらを実行して、それらが互いにどのように機能するかを確認することです。

共有してお楽しみください。

于 2010-03-11T12:09:58.230 に答える
1

おそらくインデックスがありhdId(主キーの場合はあると思いますが、そうであると思われます)、そうではありません。nameこれは、2番目のクエリが完全なテーブルスキャンを実行する必要があることを意味します。

于 2010-03-10T14:35:35.657 に答える