一般来说,查找文件中的内容与在二进制数据块中运行 SQL LIKE %x% 查询,哪个更快?

8

假设我正在设计一个工具,可以将代码片段保存在PostgreSQL/MySQL数据库或文件系统中。我想通过这些片段进行搜索。使用像Sphinx这样的搜索引擎似乎不实际,因为我们需要在搜索代码时进行精确文本匹配。

grepack一直表现出色,但是在数据库中存储东西在某些方面使大量内容更易管理。我想知道递归运行grep在目录树上与在等价数量的记录上运行类似SQL的LIKE或MySQL的REGEXP函数的查询相比,其相对性能如何。


2
这取决于你的设置,为什么不测试一下呢?你知道match against吗?参见:http://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html - Johan
4个回答

4
如果您需要在1M个文件中查找,最好的方法就是使用正则表达式遍历每一个文件。如果您使用LIKE运算符或正则表达式进行大规模查询,基本上都会重复相同的操作。
我的经验告诉我,我很少查找不包含完整单词的内容,因此您可以利用数据库来减少搜索集合。MySQL具有原生全文搜索功能,但我建议不要使用它们,因为这意味着您没有使用InnoDB。
您可以从这里阅读Postgres相关信息:http://www.postgresql.org/docs/current/static/textsearch.html
在tsvector列上创建索引后,您可以通过两个步骤执行“grep”操作,一个是立即查找可能符合条件的行,另一个是查找真正的标准。请按照格式要求返回结果。
select * from docs where tsvcol @@ :tsquery and (regexp at will);

这将比grep能做的任何事情都快得多。


1

我认为我所说的Sphinx不适合的意思是,搜索代码片段通常涉及匹配标点符号,而我认为Sphinx将其排除在索引之外。 - dan
我明白了。我熟悉Lucene,你可以用它进行源代码搜索,但你可能需要编写自己的分析器你该如何做呢?如何索引Java源文件? - bpgergo

0

互联网似乎猜测grep使用Boyer-Moore算法,这将使查询时间取决于查询大小的加性(而不是乘性)。但这并不那么相关。

我认为对于一次性搜索来说,它已经接近最优了。但在您的情况下,由于您有重复的搜索,因此可以利用其结构(例如通过索引查询中某些常见子字符串),正如bpgergo所暗示的那样,您可以做得更好。

此外,我不确定您考虑使用的正则表达式引擎是否针对非特殊查询进行了优化,您可以尝试并查看结果。

您可能希望将所有要搜索的文件保存在内存中,以避免基于硬盘的减速。除非您正在搜索大量文本,否则这应该有效。


MySQL还使用增强的Boyer-Moore算法来搜索超过给定限制的字符串(LIKEMATCH AGAINST)。详情请见:http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html。如果您使用`LIKE '%string%'`并且字符串长度大于三个字符,MySQL将使用Turbo Boyer-Moore算法来初始化该字符串的模式,然后使用该模式更快地执行搜索。 - Johan

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接