0
select  * from   FOO.MBR_DETAILS where BAR= 'BAZ' and MBR_No = '123'

実行時間 = 0.25 秒

CREATE PROCEDURE My.MEMBER_SEARCH
(
        i_BAR varchar(3),
        i_member_surname varchar(50),
        i_member_code varchar(10),
        i_member_given_name varchar(50)
)

    RESULT SETS 1
    LANGUAGE SQL
BEGIN
   DECLARE c1 cursor with return for

          select *
          FROM FOO.MBR_DETAILS m
          WHERE
            BAR= i_BAR
            and  (i_member_code = '' or  m.MBR_No = i_member_code)
            and (i_member_surname = '' or  m.surname = i_member_surname)
            and (i_member_given_name = '' or  m.given_names  LIKE  '%'||i_member_given_name||'%');


    OPEN c1;
END

call My.MEMBER_SEARCH('BAZ','','123','')

実行時間 = 1.9 秒

i_member_surname と i_member_given_name は両方とも空であるため、両方のクエリは同様の時間を持つべきだと思いました。それらは評価されません。

4

1 に答える 1

3

解決策は、柔軟なパラメーター主導の検索を実行するすべてのストアド プロシージャに対して REOPT ALWAYS を有効にすることです。

REOPT ALWAYS オプションを使用すると、オプティマイザーは入力パラメーター値を分析し、プロシージャーのコンパイル時に 1 回だけではなく、プロシージャーが実行されるたびに新しいアクセス プランを作成するように強制されます。REOPT ALWAYS では、ストアド プロシージャを実行するたびに数ミリ秒のオプティマイザ オーバーヘッドが追加されますが、ストアド プロシージャを最初にコンパイルするときにオプティマイザが推測した万能のアクセス プランを継続的に再利用するよりもおそらく高速です。 .

于 2012-06-28T03:31:55.003 に答える