MySQL 搜索查询优化:Match...Against vs %LIKE%

Pep*_*epe 2 mysql sql

我想构建我的第一个真正的搜索功能。我一直在谷歌上搜索一段时间,但无法真正下定决心并理解一切。

我的数据库存在三个 InnoDB 表:

  • 产品:包含产品信息。列:(proID主要,自动递增)、content(最多包含几百个单词)titleauthoryear、 和一堆与搜索查询无关的其他列。行数:100 到 2000。
  • 类别:包含类别信息:列:catID(小学,自动递增)catName。行数:5-30
  • 产品类别:以上两者之间的链接。每个产品可以与多个类别相关。列:(pcID主要,自动递增)、catIDproID。行数:产品数量的 1-5 倍。

我的搜索功能提供以下内容。它们不必填写。如果填写了多个,最终查询会将它们与 AND 查询连接起来:

  • 术语:搜索内容和标题字段。搜索随机词,可以添加多个词,但搜索每个词是分开的。最有可能与数据库匹配的 1 次匹配应该足以命中(OR-query)
  • 年份:在产品的年份栏上搜索。
  • 类别:可从类别列表中选择。多种可能。该表单返回所选类别的 catID。与数据库匹配的 1 次应该足以命中(或查询)
  • 作者:在author产品-列上搜索

As you may have noticed, when a category is selected, the tables products and productcategories are joined together for the search query. 两者之间还有一个外键集。

为了澄清关系,举一个应该如何解释它的例子(不搜索年份!):

搜索 WHERE (products.content = term 1 OR products.content = term 2 OR products.title = term 1 OR products.title = term 2 ......) AND (products.author = author) AND (productscategories.catID = catID1 OR productscategories.catID= catID2 ......)

另请注意,我创建了一个分页系统,在每个“页面”上仅显示 10 个结果。

我遇到的问题如下:我希望优化此搜索查询,但无法确定哪种方式最好。

大多数情况下,我发现谷歌搜索使用了LIKE %%mysqli-query。然而,有些人使用了MATCH...AGAINST. 我似乎真的很喜欢最后一个,因为我读了它可以根据相关性进行排序,并且因为它似乎使查询更容易创建(1 个匹配术语值而不是大量与LIKE %%结合OR)。不过,似乎我只会在 Term-searchfield 上使用它。但是因为MATCH...AGAINST我需要一个 MyIsam 表(对吗?),我不能使用外键来防止数据库中的错误。

MATCH...AGAINST 示例(没有年份字段、类别字段且不加入产品和产品类别):

SELECT *,MATCH (content,title) AGAINST ('search terms' IN BOOLEAN MODE) AS relevance 
FROM products WHERE (MATCH (content,title) AGAINST ('search terms' IN BOOLEAN MODE)) AND
author='author' SORT BY relevance LIMIT 10
Run Code Online (Sandbox Code Playgroud)

%LIKE% 示例(没有年份字段,类别字段并且没有加入产品和产品类别),遗憾的是没有相关性排序:

SELECT * FROM products WHERE
(content LIKE '%term1%' OR content LIKE '%term2' OR title LIKE '%term1%' OR title LIKE '%term2%')
AND (author='author') SORT BY title LIMIT 10
Run Code Online (Sandbox Code Playgroud)

CASE如果标题或内容中出现术语,我可以通过使用和添加“点”进行相关性排序?或者这会使查询对性能来说太重了吗?

那么进行这种查询的最佳方法是什么?使用 Innodb 和LIKE,或切换到 MyIsam 并使用MATCH...AGAINST进行排序?

Kay*_*son 5

您不必切换到 MyIsam。Mysql 5.6 及更高版本支持全文索引。

我通常建议使用全文索引。在您的列标题、作者、年份上创建全文索引

然后您可以同时对所有 3 个运行全文查询,并应用 IN BOOLEAN MODE 以真正缩小您的搜索范围。这当然是您必须自己决定的事情,但全文中的选项更多。

但是,如果您正在运行在范围、日期或简单字符串之间生成的查询。那么标准索引更好,但是对于在不同列中进行 tekst 搜索,全文索引是要走的路!

阅读:http : //dev.mysql.com/doc/refman/5.6/en/fulltext-search.html