仅针对 Mysql 中的 1 列进行实时搜索 - 无需任何插件

Realtime search against only 1 column in Mysql - without any plugins

然而我发现了一些关于这个的话题,但没有适合我的情况。

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

搜索请求仅在输入 3 个或更多字符时启动,并且仅在 1 个数据库列(称为 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;}
}}

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

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

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

第二个问题,对于我的情况最好的查询应该是什么,当然性能最好?因为我需要在用户输入的每个字母之后进行搜索。

我可以这样使用搜索吗?

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

不过看起来,只有当单词完全匹配标题时才会return,但是当单词是标题的一部分时return什么都没有,所以这不是一个好的解决方案。

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

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

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

如果您的 title 列有类似 utfmb4_general_ci 的排序规则,您不必担心处理 MySQL 中的大写、小写和变音符号 WHERE 子句。 MySQL 会为您完成。它真的擅长处理character sets and collations各种语言。 (这样的东西对Swedish-language用户很有帮助,MySQL的发明者是瑞典人。)

FULLTEXTNATURAL LANGUAGE MODE 可能不是此应用程序的正确方法。它适用于单词,而不是字母块。所以它可能不会给你任何东西,直到你的用户输入了一个完整的单词,而不是 stop word。而且,当您搜索只有几行的 table 时,它有点笨拙。所以,如果您刚开始,这可能是个问题。

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

对于您的 progressive-search 应用程序,您可能希望使用这两个 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 中获取整个 table 并在您的 php 程序中搜索它。

并且,使用准备好的语句。因为 cybercreeps.