2016-11-17 56 views
4

私のPL/SQLには、この大きな動的SQLがバインド変数を使用しています。 DBMS_SQLパッケージを使用して、生成された問合せをバインドおよび実行します。LIKE%演算子でバインド変数を使用する

特定の条件に基づいて、where句が動的SQLに追加されます。バインド変数にマッチするために "in"または "="を使用すると、すべて正常に動作し、結果はかなり速く返されます。

例:

(servedparty = :bv_ or servedpartyimsi = :bv_)

しかし、私は次の操作を実行したとき:

(servedpartyimei like :bv_) 

とクエリは非常に非常に非常に長い時間を要する12345679890%のような価値を提供します。

は、私はまた、「%」なしに価値を提供しますが、私はバインド変数なしでクエリを実行すると、それは同じ結果

を与え、この

(servedpartyimei like :bv_||'%')

と同じようsomehtingを試みたが、ハードコードされた値を置くだけで、結果も即座に返されます。

ここで何か問題がありますか? LIKE演算子のような変数をバインドしないでください。 アイデア

ありがとうございます。

+1

どのデータ型が 'servedpartyimei'ですか?あなたは数字の検索値を表示しています(これはIMEIであると思いますが、文字列として扱っています)。使用しているOracleのバージョンを示すことも重要です。速くて遅いバージョンの実行計画を見ることができますか? –

+0

imeiは文字列としてデータベースに格納されます。データベースのバージョンは11.2 – Tijs

+2

まだ実行計画を見て、それが何をしているのかを確認する必要があります。おそらく、他の(索引付けされた)列にもフィルターがあり、それがより適切と思われるか、または他の理由で予想している索引を使用していない可能性があります。私たちはそれが何をしているのか本当に推測することはできません、あなたが知る必要があります。 –

答えて

4

私はあなたが固定されていないOracleのバグ9197434(DBMS_SQLを使用した場合BINDが覗い起きていない)私の知る限りでは

、苦しんでいると思います。

バインド変数の覗き見を利用しないと、Oracleは、条件の右側にどのような値があるかわかりません。たとえば、 '%'とすることもできます。したがって、Oracleでは、通常のバインド変数値である行数はどれくらいになるかを前提にしています。これらの前提は非常に控えめで、オラクルがあなたが望む高速プラン(おそらくインデックスを使用)から、あなたが得ている遅いプラン(ハッシュ結合を使用している可能性が高い)から遠ざける可能性があります。

可能であれば、このバグの影響を受けないネイティブ動的SQL(つまり、EXECUTE IMMEDIATE)を使用することをお勧めします。それ以外の場合は、SQLをHINTする必要があります。

+1

同じバグの11.2バージョンは、バグ#13386678(BIND PEEKINGはDBMS_SQLで機能しません)です。 Oracleはそのバグを「修正するのは実現不可能」と判断しました。だから、回避策が必要です。 –

3

LIKEをバインド変数とともに使用すると、いくつかの古いバージョンでは、一致する行の数を前提にする必要があります。私はそれが5%、10%、どんなものでも良いかもしれないということを覚えていません(バージョンによって異なるかもしれません)。今やそれは現実と一線を画し、貧しい計画につながるかもしれません。

その名前が何を_like_with_bind_as_equality呼ば非公開(及びサポートされていない)オプティマイザパラメータがあり - すなわちtruecolumn like :bvによって返される行の数はcolumn = :bvによって返されるものと同じであると仮定したとき。だからあなたがそれを使うなら、より速い計画を得るかもしれません。 alter sessionで設定できます。

+0

と確認します。これを試しましたが、残念ながらそれは効果がありません。 – Tijs

関連する問題