2013-05-27 22 views
6

大量のゾーン(gvcodeとcgiで定義された問合せで)に定義された電話番号接頭辞のリストがあります。 与えられた番号PHONE_NRに一致する最も長いプレフィックスを効率的に見つける必要があります。ORACLEで最も長い接頭辞を検索する最速の方法

フィールド桁(+ 48%、+ 49%、+ 1%、+ 1232%という形式の接頭辞を含む)に反転LIKE句を使用します。

したがって、私はそのフィールドで通常のインデックスを使用することはできません。

gvcodeとcgiフィールド(主キーの最初の2つの列)にIOTを使用することで、大幅な改善が得られました。 私もいくつかのOracleテキストインデックスを見ましたが、テーブルの短い接頭辞を持つより長い入力と一致するものを見つけることができません。

この方法よりも速い検索を実行する方法はありますか?

これは、すべての一致するプレフィックスのリストを与えるクエリです(後でそれを桁の長さでソートします)。

+0

'substr(digits、2、length(digits)-1)'に関数ベースのインデックスを作成し、クエリにwhere句を追加すると、 'substr(digits、2、length(digits)-1 )<= PHONE_NR'あなたはいくつかの改善を見ることができます –

+0

'とsubstr(数字、1、長さ(数字)-1)<= PHONE_NR'( '+'を削除する必要はありません) –

答えて

1

「数字」のインデックスに加えて、rpad(substr(digits,1,length(digits)-1), 10, '9')にインデックスを作成できます。 「10」はサポートしたい最大長です。rpad(substr(digits,1,length(digits)-1), 10, '9') >= PHONE_NR

あなたのSQLは次のようになります:ここで

select t.gvcode, t.digits 
from NUMBERS t 
    where 
     t.gvcode=ZONE_SET_CODE 
     and t.cgi=cgi_f 
     and PHONE_NR like t.digits 
     and substr(digits, 1, length(digits)-1) <= PHONE_NR 
     and rpad(substr(digits,1,length(digits)-1), 10, '9') >= PHONE_NR 
order by length(digits) desc 

は、私は同じ問題を持っていたので、ちょうど書き込み、オーケーsqlfiddle

0

これは本当に役立つとは思っていませんが、試してみる価値はあると思います。

次に、あなたのクエリで使用すると、別の条件を追加することができます(これは「%」なしでちょうどインデックス桁にある)substr(digits, 1, length(digits)-1)

を関数ベースのインデックスを作成します。

AND substr(digits, 1, length(digits)-1) <= PHONE_NR 

Here is a sqlfiddle demo

考えてみると字句の比較では、PHONE_NRの後にあるすべての数字を切り捨てることができます

1

私は愚かに聞こえるかもしれないが、私はこのような問題に遭遇したとき、私はほとんどの非スペース効率強引な方法で行ってきました:

は言うことができます:

L=length of longest prefix to match (without obvious +, of course) 

は、例えば、それらを命名L追加フィールドを追加します

UPDATE NUMBERS set P1=SUBSTR(PHONE_NR,1,1), P2=SUBSTR(PHONE_NR,1,2), ..., PL=SUBSTR(PHONE_NR,1,L) 

と、これらのフィールドは、(将来的にあなたはでこれを行うことができ、P1, P2,...,PL

更新トリガーも)

ここで、インデックスを作成して好きなものと比較するためのLフィールドがあります。

0

例である。あなたは、where句に条件を追加します プレフィックスの長さの範囲を知っている場合は、次のようなことができます。次の例では、接頭辞の長さを2〜6と仮定しています。

select t.num, coalesce(p6.PREFIX, p5.PREFIX, p4.PREFIX, p3.PREFIX, p2.PREFIX) PREFIX 
    from NUMBERS t 
LEFT OUTER JOIN PREFIXES p2 ON substr(t.num,1,2)=p2.PREFIX 
LEFT OUTER JOIN PREFIXES p3 ON substr(t.num,1,3)=p3.PREFIX 
LEFT OUTER JOIN PREFIXES p4 ON substr(t.num,1,4)=p4.PREFIX 
LEFT OUTER JOIN PREFIXES p5 ON substr(t.num,1,5)=p5.PREFIX 
LEFT OUTER JOIN PREFIXES p6 ON substr(t.num,1,6)=p6.PREFIX 

等しい結合は得られる限り良好です。

私はそれが同じ問題に

Sqlfiddle linkをつまずく誰もがそのスクリプトまだすべての一致を与える代わりにのみ、最長1

sailawayの答えから変更役に立てば幸い、それはここで、他の可能な解決策よりもずっといい実行されることを信じています
関連する問題