快速比较大量二进制数据

时间:2012-07-23 11:53:06

标签: mysql database performance nosql

我有一个数据库,包含大量图像(数百万)和这些图像的内容签名(由libpuzzle生成),我需要进行比较。

我已经运行了许多不同的替代方案来尝试使其高效,包括各种搜索算法(levenshtein difference目前运行速度最快)和各种数据点作为预过滤器(将比较缩小到只有几千张图片的批量)但我尝试的一切仍然是减缓生产使用的方法。我每天要添加几千张图片,这些图片需要将其签名与整个集合中的其他内容进行比较。

我使用的两种主要存储方法是CouchDb和MySql,两者都需要数据存储超过10s的演出,而在几百万条记录之后,MySql的运行速度太慢(即使结果缓存和索引键大小变化也是如此) ,索引太大了,使用类似to this one的方法,这是很好但仍然很慢),而在Couch上它似乎无法处理大型索引。我还考虑过像Amazon SimpleDB这样可以解决存储问题的服务,但考虑到这些大型索引的内存需求,我预计会非常昂贵,并且可能不会比Couch更好。

表结构很简单:

ImageId int(11),
Signature VARCHAR(1020) //implemented as text

期望的结果应该是给定ImageId的ImageId列表。一个简单的自连接(ON比较函数)太慢了。

我的实施是比较现有图像,并持续比较新图像与现有基础,以实现这两个目标... 1)识别相同或非常接近相同的图像(包括调整大小,作物和未成年人)颜色变化,以及2)识别相似图像以帮助可能对类似视觉内容的图像感兴趣的图像搜索。 libpuzzle库提供了一个可以用于两者的分数(前者使用> 95%,后者使用> 80%。)

基本上我的问题是,有没有人知道任何一个 a)不同的数据存储平台
b)使用MySql的技术
c)或其他一些(可能是定制的)方法 哪个可用于以非常有效的方式线性比较大量二进制数据?

1 个答案:

答案 0 :(得分:1)

你所链接的“优秀方法”实际上就是答案,但它有一个主要问题:它不应该在MySQL中完成,这对于那种搜索来说很糟糕,但在Solr或Sphinx中是正是为此而建。

因为我知道Solr在这里你是如何做到的:

使用具有恒定长度(最大ngram长度=最小ngram长度)的ngram过滤器将索引签名标记为文本 - 这会将签名从链接的答案拆分为“单词”(标记)。

<fieldType 
   name="signatureNgrams" 
   stored="false" 
   class="solr.StrField"> 
 <analyzer type="index"> 
   <tokenizer 
       class="solr.analysis.NGramTokenizerFactory" 
       minGramSize="4" 
       maxGramSize="4" 
       /> 
   <filter class="solr.LowerCaseFilterFactory"/> 
 </analyzer> 
</fieldType>

使用http://wiki.apache.org/solr/DisMaxQParserPlugin#mm_.28Minimum_.27Should.27_Match.29定义最小相似度(必须匹配多少个ngram)。