2016-06-28 11 views
3

データベースの列に文字列で表が作成されています。私は、バインドされた変数で列のハミング距離を計算し、別のステートメントを使用して、ハミング距離が3以下のすべての文字列値を出力しています。ハミング距離を計算するためのインデックスアクセス

文字列値がバインドされているため私が知る限り、その関数は静的パラメータを持つ必要があるので、私は希望の結果に仮想列を使用することができません。また、私の出力は派生列なので、関数ベースのインデックスは使用できません。

フルテーブルスキャンを実行せずにクエリを最適化する代替ソリューションはありますか?現在のところ、スキャンには5〜7秒かかるので、これを300ミリ秒に減らしたいと思います。ありがとうございました。ここで

は、ソースコードの一部です:明確化のため

CREATE OR REPLACE FUNCTION HAMMING_DIS(string1 IN varchar2, string2 IN varchar2) 
RETURN number IS 
distance number := 0; 
BEGIN 
    FOR counter IN 1..length(string1) LOOP 
     IF substr(string1, counter, 1) = substr(string2, counter, 1) THEN 
     distance:= distance + 1; 
     END IF; 
    END LOOP; 
RETURN distance; 
END; 

SELECT * FROM 
(SELECT FULL_NM AS FULL_NAME, HAMMING_DIS(FIRST_NM,'&A') AS HAMMING_DISTANCE 
FROM STRINGS_OF_NAMES 
) 
WHERE HAMMING_DISTANCE > 3; 
+0

あなたは正確に何を比較していますか?変数を持つ列?その列の1つおきのインスタンスがある列?また、値についていくつかの情報を教えてください。彼らはいつも同じ長さですか?そうでない場合は、関数やクエリが異なる長さの値をスローする必要があると仮定します。 「3以下」は静的であるか、または異なる値を比較したいですか? –

+0

PL/SQL関数を使用してハミング距離を計算していますか?はいの場合は、この機能のソースコードを表示してください。主にSQL-PL/SQLのコンテキスト切り替えによって影響を受ける可能性があります。 – krokodilko

答えて

1

おかげで...私は私の他の回答を削除します。

あなたは常にハミング距離< 3(例えばない< 3時には< 5他の回)と で文字列を検索したい...場合、これらは大きなIFSは...

  • A)
  • B)あなたのテーブルがある静的あなたは多分事実を利用することができ、その後

BITMAP索引の使用を可能にするのに十分、そのクエリへの答え最初の4文字に少なくとも2つの一致が必要です。だから、

CREATE TABLE matt1 (id number, str varchar(30)); 

INSERT INTO matt1 SELECT rownum, dbms_random.string('U', dbms_random.value(1,30)) from dual connect by rownum <= 10000; 

CREATE BITMAP INDEX i1 ON matt1 (substr(rpad(str,4,' '),1,1)); 
CREATE BITMAP INDEX i2 ON matt1 (substr(rpad(str,4,' '),2,1)); 
CREATE BITMAP INDEX i3 ON matt1 (substr(rpad(str,4,' '),3,1)); 
CREATE BITMAP INDEX i4 ON matt1 (substr(rpad(str,4,' '),4,1)); 


SELECT m.*, hamming_dis(str,:input) FROM matt1 m WHERE 
(
(substr(rpad(str,4,' '),1,1) = substr(rpad(:input,4,' '),1,1) AND 
substr(rpad(str,4,' '),2,1) = substr(rpad(:input,4,' '),2,1)) 
OR 
(substr(rpad(str,4,' '),1,1) = substr(rpad(:input,4,' '),1,1) AND 
substr(rpad(str,4,' '),3,1) = substr(rpad(:input,4,' '),3,1)) 
OR 
(substr(rpad(str,4,' '),1,1) = substr(rpad(:input,4,' '),1,1) AND 
substr(rpad(str,4,' '),4,1) = substr(rpad(:input,4,' '),4,1)) 
OR 
(substr(rpad(str,4,' '),2,1) = substr(rpad(:input,4,' '),2,1) AND 
substr(rpad(str,4,' '),3,1) = substr(rpad(:input,4,' '),3,1)) 
OR 
(substr(rpad(str,4,' '),2,1) = substr(rpad(:input,4,' '),2,1) AND 
substr(rpad(str,4,' '),4,1) = substr(rpad(:input,4,' '),4,1)) 
OR 
(substr(rpad(str,4,' '),3,1) = substr(rpad(:input,4,' '),3,1) AND 
substr(rpad(str,4,' '),4,1) = substr(rpad(:input,4,' '),4,1)) 
) 
AND hamming_dis(str,:input) <= 3; 

あなたがBITMAP ORBITMAP ANDな操作の多くを実行計画が表示されるはずです。

実際に正確なハミング距離を計算する必要がある行の数を制限するため、これは高速になる可能性があります。

注:< = 3ではなく、<であることがわかりました。3.アプローチは、ポイントまで拡張可能である必要があります。