我有以下问题:
我正在寻找相似之处。因此,我有一个包含200000个条目的大型源表和包含10000个条目的第二个表。现在我正在为每个表检索一个条目集,并将源表中的每一行与java中第二个表中的每一行进行比较(我使用的是一些NeedleMan Gotoh算法和类似的更复杂的算法)。这意味着10亿次比较,这太过分太慢......
目标是一个包含所有相似性的表(来自源表的id,来自第二个表的id和相似度值)或至少类似于每个条目的最佳匹配(或最佳x匹配)......
有人可以给我一些建议,在“正常”的时间内进行这样的计算吗?
修改
主表
---+------+-------------+---------+-------+
id | name | address | country | plz | ...
---+------+-------------+---------+-------+
20 | Sony | Main Str. 1 | US | 10000 |
---+------+-------------+---------+-------+
第二张表
---+------+-------------+---------+-------+
id | name | address | country | plz | ...
---+------+-------------+---------+-------+
30 | Soni | MainStr. 1 | US | 10000 |
---+------+-------------+---------+-------+
目标(相似表):
---+---------------+--------------+-----------+
id | id_source_tbl | id_second_tbl| similarity|
---+---------------+--------------+-----------+
1 | 20 | 30 | 0.99 |
---+---------------+--------------+-----------+
simil_value是一个值,表示源表中的公司与第二个表中的公司相同的可能性
结果表明,这两行代表同一家公司...两个条目只是因为小错别字而有所不同......(0.99是相似度而且非常高=>公司是相同的) 使用needleman wunsch gotoh算法计算相似度(比较char为char并考虑字符串中的位置等等...错别字应该导致高相似度值)
答案 0 :(得分:1)
这听起来像是一个令人尴尬的并行问题,所以作为第一步,您可以在多个核心和机器上进行分析。
答案 1 :(得分:1)
允许MySQL执行数据选择而不是检索海量数据集然后使用您自己的算法对其进行过滤通常更有意义。听起来你所做的只是一个相当简单的连接操作,例如:
SELECT source_id_column, second_id_column, similarity_column
FROM source_table, second_table
WHERE source_table.similarity_column = second_table.similarity;
答案 2 :(得分:0)
在SQL中,您可以将其表达为:
选择t1.id为id1,t2.id为id2, calculate_similarity(t1.name,t2.name)作为相似度 从t1交叉连接 T2
现在,您要将相似性表定义为:
create table similarity (
SimilarityID int not null auto_increment,
id1 int,
id2 int,
similarity float
)
然后插入:
insert into similarity(id1, id2, similarity)
select t1.id as id1, t2.id as id2,
calculate_similarity(t1.name, t2.name) as similarity
from t1 cross join
t2
SQL引擎应该并行进行交叉连接以及相似度计算。也许您有办法限制查询,例如要求公司处于相同的状态或以相同的字母开头。
答案 3 :(得分:0)
实际上,我自己解决了这个问题......
我的解决方案如下:
1)不要重复使用连接,始终用相应的ResultSet关闭它们
2)使用交易
3)将工作分成线程
4)如果你像我一样,有单行结果(一个条目的所有相似之处)并且想要在这个子结果上计算某些东西(就像在我的情况下,对于我想要计算等级的所有相似性),在java中执行此操作并使用subresult !!!!而不是之后在mysql
对我而言,结果是大约1天的计算时间,而不是3周......
感谢您的帮助