2

Oracle でクエリを実行すると、非常に奇妙な動作が発生します。クエリ自体は膨大で非常に複雑ですが、実行するたびに基本的に同じです。ただし、小さい結果セットを返すと、実行が遅くなるようです。私が挙げることができる最良の例は、このフィルターを設定すると、

and mgz_query.IsQueryStatus(10001,lqo.query_id)>0 

12,429 件のレコードのうち 960 件を返すと、約 1.9 秒の実行時間が表示されます。ただし、フィルターを次のように変更すると、

and mgz_query.IsQueryStatus(10005,lqo.query_id)>0

12,429 件のレコードのうち 65 件を返すと、約 6.8 秒の実行時間が表示されます。もう少し深く掘り下げると、小さな結果セットは大きな結果セットよりもかなり多くのバッファ取得を実行しているように見えることがわかりました。これは私には完全に直感に反するようです。

これが実行されているクエリの長​​さは約 8000 文字です (誰かがそれを望まない限り、クエリ全体でこの投稿を乱雑にするつもりはありません)。その巨大なサイズとは別に、効率的です。

使用中のフィルターは、以下の関数を介して実行されます。

Function IsQueryStatus(Pni_QueryStateId        in number,
                         Pni_Query_Id       in number) return pls_integer as
    vn_count pls_integer;
  Begin
    select count(1)
      into vn_count
     from m_query mq
    where mq.id = Pni_Query_Id
      and mq.state_id = Pni_QueryStateId;

    return vn_count;
  End;

小さな結果セットのパフォーマンスが大きな結果セットよりもはるかに悪い原因についてのアイデアはありますか?

4

1 に答える 1

3

何かがセットに含まれていないことを判断するのに、セットに含まれているかどうかを判断するよりもはるかに時間がかかる状況に直面していると思います。これは非常に頻繁に発生する可能性があります。たとえば、 にインデックスがある場合、句がm_query(id)どのように実行されるかを考えてみましょう。where

(1) 値Pni_Query_Idはインデックスで検索されます。一致するものはありません。クエリは の値で実行されます0

(2) たくさんの試合があります。state_idでは、が配置されているページを取得して、 と比較してみましょうPni_QueryStateId。ああ、それはもっと多くの仕事です。

その場合は、インデックスをオンにm_query(id, state_id)するとクエリに役立ちます。

ちなみに、これは句内の関数呼び出しのみwhereが変更されていると仮定しています。より少ない行を取得するための他の変更がある場合は、この関数を呼び出す回数が減っているだけかもしれません。

于 2013-07-02T19:58:01.017 に答える