我正在尝试为我的网站创建一个小搜索。我尝试过使用全文索引搜索,但我永远无法使用它。以下是我的想法:
if(isset($_GET['search'])) {
$search = str_replace('-', ' ', $_GET['search']);
$result = array();
$titles = mysql_query("SELECT title FROM Entries WHERE title LIKE '%$search%'");
while($row = mysql_fetch_assoc($titles)) {
$result[] = $row['title'];
}
$tags = mysql_query("SELECT title FROM Entries WHERE tags LIKE '%$search%'");
while($row = mysql_fetch_assoc($tags)) {
$result[] = $row['title'];
}
$text = mysql_query("SELECT title FROM Entries WHERE entry LIKE '%$search%'");
while($row = mysql_fetch_assoc($text)) {
$result[] = $row['title'];
}
$result = array_unique($result);
}
所以基本上,它会搜索数据库中所有条目的所有标题,正文和标签。这种方法效果不错,但我只是想知道它的效率如何?这也仅适用于小型博客。无论哪种方式,我只是想知道这是否可以更有效。
答案 0 :(得分:22)
无法使LIKE '%pattern%'
查询有效。一旦获得大量数据,使用这些通配符查询的速度比使用全文索引解决方案要慢几百或几千倍。
你应该看看我为MySQL大学所做的演示: http://www.slideshare.net/billkarwin/practical-full-text-search-with-my-sql
以下是如何让它发挥作用:
首先确保您的表使用MyISAM存储引擎。 MySQL FULLTEXT索引仅支持MyISAM表。 (编辑11/1/2012: MySQL 5.6为InnoDB表引入了FULLTEXT索引类型。)
ALTER TABLE Entries ENGINE=MyISAM;
创建全文索引。
CREATE FULLTEXT INDEX searchindex ON Entries(title, tags, entry);
搜索它!
$search = mysql_real_escape_string($search);
$titles = mysql_query("SELECT title FROM Entries
WHERE MATCH(title, tags, entry) AGAINST('$search')");
while($row = mysql_fetch_assoc($titles)) {
$result[] = $row['title'];
}
请注意,您在MATCH
子句中命名的列必须与您在全文索引定义中声明的列的顺序相同。否则它将无效。
我尝试使用全文索引搜索,但我无法让它工作......我只是想知道这是否可以提高效率。
这就像是说:“我无法弄清楚如何使用这种电锯,所以我决定用小折刀砍掉这棵红木树。我怎么能像电锯那样做这项工作?”
关于搜索匹配超过50%的字词的评论。
MySQL手册说this:
需要绕过50%限制的用户可以使用布尔搜索模式;见Section 11.8.2, “Boolean Full-Text Searches”。
this:
自然语言的50%门槛 搜索是由 选择了特定的加权方案。至 禁用它,查找以下内容 存储行/ myisam / ftdefs.h:
#define GWS_IN_USE GWS_PROB
将该行更改为:
#define GWS_IN_USE GWS_FREQ
然后重新编译MySQL。没有必要 在这种情况下重建索引。
此外,您可能正在搜索停用词。这些是全文搜索忽略的词,因为它们太常见了。单词如“the”等。见http://dev.mysql.com/doc/refman/5.1/en/fulltext-stopwords.html
答案 1 :(得分:5)
使用LIKE
NOT 全文。
您需要使用... WHERE MATCH(column) AGAINST('the query')
才能访问全文搜索。
答案 2 :(得分:4)
MySQL全文搜索工作 - 我会调查并调试它而不是尝试这样做。做3个单独的MySQL查询不会有任何效率。
如果您想提高效率,可以将一个查询中的LIKE
语句与它们之间的OR
分开。