首页 > 解决方案 > 仅针对 Mysql 中的 1 列进行实时搜索 - 无需任何插件

问题描述

但是,我发现了一些关于此的线索,但没有适合我的情况。

我的移动应用程序中有一个搜索字段,在文本更改后,实时搜索通过调用我的 API 运行。

搜索请求仅在输入 3 个或更多字符时开始,并且仅在 1 个 DB 列中搜索,称为 TITLE。因此,每次用户输入一个字母时,都会有一个查询正在搜索它。

目前我有这样的(我知道这个解决方案非常糟糕)。$searchedword 是用户输入的单词:

if (!empty($searchedword)&&strlen($searchedword)>2 ) {$searchedword=strtolower($searchedword);

$sql = "SELECT  * FROM TABLE ";$result = $mysqli->query($sql); $output='';
  if ($result->num_rows > 0) {
while($data=$result->fetch_array()) {
      $title=strtolower($data['title']);$content=$data['content'];
if (strpos($title,$searchedword) !== false ) {$output.=$title.','.$content;}
}}

所以这只是检查数据库中的标题是否包含搜索的单词。这很好用,但从性能上我认为它很糟糕,因为每次用户在搜索字段中输入一个字母时,每次都会查询表中的所有数据并查找该单词。

我想重新创建我的代码以满足最佳性能。

所以我的第一个问题是,我应该在 DB 的 TITLE 列中添加一个 FULLTEXT INDEX,它会有所帮助还是只会增加磁盘空间?因为我只是在搜索 1 列,而在此列中只是一个标题(最多 1 或 2 个字)。

第二个问题,对于我的案例,最好的查询应该是什么,当然还有最好的性能?因为我需要搜索用户输入的每个字母。

我可以这样使用搜索吗?

 SELECT * FROM TABLE WHERE MATCH (title) AGAINST ('$searchedword' IN NATURAL LANGUAGE MODE) 

但是看起来,只有当单词与标题完全匹配时才会返回,但当单词是标题的一部分时不返回任何内容,因此这不是一个好的解决方案。

唯一可行的解​​决方案是:

SELECT * FROM TABLE WHERE title LIKE '%$searchedword%'  "

但是性能呢?而且我不明白这是如何工作的,因为 searchedword 被转换为小写字母,并且我已经从该单词中删除了重音符号,并且 DB 中的 TITLE 列有重音符号和大写字母,但是这个搜索效果很好!

标签: mysqlfull-text-search

解决方案


如果您的title列具有类似 的排序规则utfmb4_general_ci,则不必担心在 MySQLWHERE子句中处理大写、小写和变音符号。MySQL 会为你做这件事。它非常擅长处理各种语言的字符集和排序规则。(这些东西对瑞典语用户很有帮助,MySQL 的发明者是瑞典人。)

FULLTEXTwithNATURAL LANGUAGE MODE可能不是此应用程序的正确方法。它适用于单词,而不是字母块。因此,在您的用户输入整个单词而不是停用词之前,它可能不会给您任何东西。而且,当您搜索只有几行的表时,这有点松鼠。所以,如果你刚刚开始,这可能是个问题。

它确实按照匹配的紧密程度对结果进行排序,因此最有可能命中的是第一个。因此,如果您知道要搜索一个短语,那就太好了。

对于您的渐进式搜索应用程序,您可能希望使用这两个LIKE查询之一。

SELECT title FROM tbl WHERE title LIKE CONCAT('$searchedword', '%') /*insecure*/

或者这个慢得多,但在标题的任何地方都可以找到您的部分匹配,而不仅仅是在开头。

SELECT title FROM tbl WHERE title LIKE CONCAT('%', '$searchedword', '%') /*insecure*/

在您从用户那里收集到至少几封信之前,请避免运行这些查询,否则您会得到很多荒谬的结果。

在这些情况下说不SELECT title,并在列SELECT *上创建一个普通索引。title这样 MySQL 就可以从索引中满足整个查询,这将使其更快。

并且,使用 MySQL 的WHERE功能进行匹配。不要从 MySQL 中获取整个表并在您的 php 程序中搜索它。

并且,使用准备好的语句。因为网络蠕虫。


推荐阅读