0

これをサブ選択として (他の 2 つのテーブルを結合する単純なクエリで) 使用していますが、ご想像のとおり、実行には時間がかかります。ここまで6時間以上。これがこれを行う唯一の方法ですか?サブ選択の代わりに別の JOIN を実行すると、少し役立つことはわかっています。しかし、主なボトルネックはこれらすべての OR と部分文字列です。

SELECT ex_array
FROM   service_x 
WHERE  
   ( substr(ex_array,1,2) = 'FW' OR substr(ex_array,3,2) = 'FW' OR substr(ex_array,5,2) = 'FW' OR substr(ex_array,7,2) = 'FW' OR substr(ex_array,9,2) = 'FW' OR substr(ex_array,11,2) = 'FW' ) 
OR ( substr(ex_array,1,2) = 'IL' OR substr(ex_array,3,2) = 'IL' OR substr(ex_array,5,2) = 'IL' OR substr(ex_array,7,2) = 'IL' OR substr(ex_array,9,2) = 'IL' OR substr(ex_array,11,2) = 'IL' )  
OR ( substr(ex_array,1,2) = 'IN' OR substr(ex_array,3,2) = 'IN' OR substr(ex_array,5,2) = 'IN' OR substr(ex_array,7,2) = 'IN' OR substr(ex_array,9,2) = 'IN' OR substr(ex_array,11,2) = 'IN' )  
OR ( substr(ex_array,1,2) = 'IK' OR substr(ex_array,3,2) = 'IK' OR substr(ex_array,5,2) = 'IK' OR substr(ex_array,7,2) = 'IK' OR substr(ex_array,9,2) = 'IK' OR substr(ex_array,11,2) = 'IK' )  
OR ( substr(ex_array,1,2) = 'IH' OR substr(ex_array,3,2) = 'IH' OR substr(ex_array,5,2) = 'IH' OR substr(ex_array,7,2) = 'IH' OR substr(ex_array,9,2) = 'IH' OR substr(ex_array,11,2) = 'IH' )  
OR ( substr(ex_array,1,2) = 'KP' OR substr(ex_array,3,2) = 'KP' OR substr(ex_array,5,2) = 'KP' OR substr(ex_array,7,2) = 'KP' OR substr(ex_array,9,2) = 'KP' OR substr(ex_array,11,2) = 'KP' )  
)
4

4 に答える 4

3

あなたが試すことができることの1つは、関数ベースのインデックスを使用することです。具体的には、substr(ex_array,3,2) や substr(ex_array,9,2) などに関数ベースのインデックスを作成します。

ただし、多くのインデックスになる可能性があるため、いくつかのテストを実行して、どれだけ役立つかを比較検討する必要があります。しかし、それは始めるためのアイデアです。

8i以降だと思います。

于 2012-04-19T19:44:02.890 に答える
1

どうですか、この構造…

INSTR( ex_array, 'FW' ) IN (1,3,5,7,9,11)

少なくとも、文字列の解析を 1 回だけ行うことになります...

于 2012-04-19T20:01:47.910 に答える
1

たぶんregexp_likeで:

REGEXP_LIKE(ex_array, '^(.{2}){0,5}(FW|IL|IN|IK|IH|KP).*$')

(正規表現の方がうまく書けるかも…)

dcpが提案するように、関数ベースのインデックスを追加することもできます (ただし、必要なのは 1 つだけです)。

create index fbIndex on service_x (REGEXP_INSTR(ex_array, '^(.{2}){0,5}(FW|IL|IN|IK|IH|KP).*$'));

使用するクエリを変更します。

REGEXP_INSTR(ex_array, '^(.{2}){0,5}(FW|IL|IN|IK|IH|KP).*$') = 1
于 2012-04-19T20:36:21.440 に答える
0

必要なクエリの選択性を考えると、利用可能な情報があれば、次のことをお勧めします。

1) ex_array のインデックス (できれば ex_array のみ、またはインデックスの先頭に ex_array を使用)。

2) クエリを変更します。フィルター基準を追加すると、次のようになります。

... and (Ex_array like '%FW%' OR ex_array like '%IL%' or ex_aray like ....など、6 つのケースのそれぞれをカバーします。インデックスを配置すると、インデックス範囲スキャンが有効になり、 1,220 万行を、関心のある 6 つの文字列の 1 つを含む行のみに変換します。これらの行のみに substr ロジックが適用され、予想される 175K が残ります。

原則として、これにより効率が向上します。ただし、データの分布に大きく依存します (たとえば、元のクエリで指定された場所ではなく、1200 万行すべてに 6 つの文字列のいずれかが含まれている可能性があります。この場合、提案された変更は元の変更よりも効率が悪い可能性があります。クエリ)。他のオプションがあるかもしれませんが、より正確にするための計画の説明など、より多くの情報が必要です。

これが役に立てば幸いです-頑張ってください!!

于 2012-04-20T20:32:49.297 に答える