MySQL中的文本搜索 - 性能和替代方案

时间:2012-01-24 01:33:01

标签: mysql sql lucene indexing full-text-search

我在MySQL中有一组这样的表([table_name] _id引用的外键):

Articles(id, author_id, title, date, broad_search, ...)
Keywords(id, article_id, keyword (varchar))
Authors(id, name, ...)
Attachments(id, article_id, url, ...)

我们最关心的是'关键字',所以我只提到它的索引:

id - Primary - BTREE
(article_id,keyword) - Unique - BTREE
keyword - BTREE
article_id - BTREE

每篇文章都有关联的关键字列表。 Articles中的“broad_search”列指出该特定文章是否可以与关键字(broad_search = 1)进行广泛匹配,或者是否必须与关键字(broad_search = 0)完全匹配。我有一个SELECT查询,它根据关键字,broad_search参数和其他过滤条件提取文章列表。

$sql = "SELECT *
FROM Keywords k, Attachments at, Articles ar, Authors a (2 more tables)
WHERE 
((ar.broad_search=0 AND k.keyword = '$Keyword')
OR (ar.broad_search=1 AND (INSTR('$Keyword', k.keyword)>0 OR k.keyword like '%$Keyword%')))
AND at.article_id = ar.id
AND a.id = ar.author_id 
... (more conditions)
LIMIT 20";

文章可以设置为braod match或完全匹配,我正在尝试根据关键字获取它们的列表。

完全匹配很简单。但广泛匹配有各种情况,不允许我使用像'%search_term%'这样的简单外卡模式。一个例子:

Keywords for a broad match article = {books, used books, reading books, popular book}
search term = new books

现在,我们不能使用mysql通配符字符串匹配,因为'%new books%'将不匹配任何关键字,但需要检索它,因为搜索项包含关键字的子字符串(broad_search = 1)。因此,broad_search有两种类型:关键字“二手车”中的search_term =“cars”和关键字“cars”中的搜索词=“二手车”。

如果broad_search = 0,请进行完全匹配。如果broad_search = 1,则匹配两种情况:

 ((ar.broad_search=0 AND k.keyword = '$Keyword')
        OR (ar.broad_search=1 AND (INSTR('$Keyword', k.keyword)>0 OR k.keyword like '%$Keyword%')))

我写的查询完美地完成了这项工作。但问题在于性能。关键字表非常大,有超过100,000行并且不断增长。此外,这是一个高负载的应用程序,并由于它收到的大量请求而导致我的服务器死亡。

我觉得这不是执行文本搜索的正确方法。我尝试了关于全文搜索的mysql文档,但我不太了解它的应用程序,如果它符合我的搜索条件。另外,我在考虑Apache Lucene是否是更好的选择,但我之前没有使用它,所以不太确定(此查询在PHP脚本中运行)。

我应该如何实施?它是索引问题,还是MySQL INSTR函数效率低下,还是应该使用完全不同的方法?

1 个答案:

答案 0 :(得分:1)

MySQL不是搜索引擎,它是一个关系数据库管理系统(RDBMS)。但是,您可以实现本机MySQL工具来模拟全文搜索功能,例如将搜索表设置为MyISAM并向要搜索的列添加FULLTEXT索引。您可以阅读MySQL docs以获取有关MySQL如何支持全文搜索的更多信息。

即使您使用全文搜索查询以您想要的方式工作,您仍然会错过真正的搜索引擎(Lucene)支持的一系列功能。诸如构面,空间搜索,结果提升,加权等功能。我建议您阅读Apache SOLR,因为它支持所有这些功能等等。甚至可以使用PHP SOLR API来访问SOLR实例。

我并不是说完全放弃MySQL,而是将其用于预期目的,持久存储可查询的数据,以及可用于填充搜索引擎索引的数据。 SOLR甚至还有一个内置的文档导入处理程序,它允许您设置要在MySQL数据库中批量导入数据时使用的数据库查询。

学习曲线相对较高,就像学习大多数新技术一样,但是当你完成后,你会想到如何在不使用真正的全文搜索引擎的情况下获得成功。