计算汉明距离的索引访问

Posted

技术标签:

【中文标题】计算汉明距离的索引访问【英文标题】:Index Access for Calculating Hamming Distance 【发布时间】:2016-10-31 01:36:23 【问题描述】:

我有一个在数据库列中填充了字符串的表。我正在使用绑定变量计算列的汉明距离,然后使用单独的语句输出所有字符串值,例如,汉明距离小于或等于 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;

【问题讨论】:

你到底在比较什么?带有变量的列?一列与该列的所有其他实例?另外,你能给我们一些关于价值观的信息吗?它们总是具有相同的长度吗?如果不是,那么我假设函数或查询需要抛出不同长度的值。 “小于等于3”是静态的,还是要比较不同的值? 您是否使用 PL/SQL 函数来计算汉明距离?如果是,请显示此功能的源代码。可能是您主要受 SQL-PL/SQL 上下文切换的影响。 【参考方案1】:

感谢您的澄清...我将删除我的其他答案。

如果……这些都是大如果……

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 操作的执行计划。

这可能会更快,因为您将限制实际需要计算准确汉明距离的行数。

注意:我看到你想要

【讨论】:

以上是关于计算汉明距离的索引访问的主要内容,如果未能解决你的问题,请参考以下文章

算法 - 计算汉明距离

R语言计算汉明距离(Hamming Distance)实战

OpenCV图像哈希计算及汉明距离的计算

461. 汉明距离

快速计算具有最小汉明距离的对

汉明距离