优化mysql全文搜索

yul*_*ika 15 php mysql full-text-search

我想在我的网站上用全文搜索.我需要一个分页搜索.我的数据库每桌有50,000多行.我改变了我的表并使其(title,content,date)成为索引.表总是更新,还有一个id自动增加的列.最新date的总是在表的末尾.

date  varchar(10)
title  text
content  text
Run Code Online (Sandbox Code Playgroud)

但整个查询时间会花费1.5+ seconds.我通过谷歌搜索了很多文章,有人写道,只有限制Index字段字长可以帮助搜索更快.但作为一个text类型,它can not改变一定长度一样,(我试图ALTER TABLE table_1 CHANGE标题titleTEXT(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,不工作)

date  varchar(10)
title  text(500)
content  text(1000)
Run Code Online (Sandbox Code Playgroud)

所以,除了Sphinx和第三部分脚本.如何用sql优化全文搜索?查询代码在这里:

(SELECT 
title,content,date 
FROM table_1 
WHERE MATCH (title,content,date) 
AGAINST ('+$Search' IN BOOLEAN MODE)) 
UNION 
(SELECT 
title,content,date 
FROM table_2 
WHERE MATCH (title,content,date) 
AGAINST ('+$Search' IN BOOLEAN MODE)) 
Order By date DESC
Run Code Online (Sandbox Code Playgroud)

谢谢.

Den*_*rdy 10

根据问题的后续评论,您的列上有btree索引而不是全文索引.

对于针对搜索的MATCH(标题,内容),您需要:

CREATE FULLTEXT INDEX index_name ON tbl_name (title,content);
Run Code Online (Sandbox Code Playgroud)

我不确定它会接受那里的日期字段(后者可能无论如何都不相关).


Rol*_*DBA 6

我有一个全面的计划,你可以尽可能彻底地优化MySQL的FULLTEXT索引

你应该做的第一件事是:摆脱禁用词列表

多年来,这让一些人感到恼火,因为他们不知道FULLTEXT索引有600多个单词被排除在外.

以下是这些停用词的表格视图.

有两种方法可以绕过这个

绕过选项1)创建自定义禁用词列表.

您实际上可以向mysql提交您首选的停用词列表.这是默认值:

mysql> show variables like 'ft%';
+--------------------------+----------------+
| Variable_name            | Value          |
+--------------------------+----------------+
| ft_boolean_syntax        | + -><()~*:""&| |
| ft_max_word_len          | 84             |
| ft_min_word_len          | 4              |
| ft_query_expansion_limit | 20             |
| ft_stopword_file         | (built-in)     |
+--------------------------+----------------+
5 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

好的,不要让我们创建我们的禁用词列表.我通常将英文文章设为唯一的停用词.

echo "a"    > /var/lib/mysql/stopwords.txt
echo "an"  >> /var/lib/mysql/stopwords.txt
echo "the" >> /var/lib/mysql/stopwords.txt
Run Code Online (Sandbox Code Playgroud)

接下来,将选项添加到/etc/my.cnf并允许使用1个字母,2个字母和3个字母的单词

[mysqld]
ft_min_word_len=1
ft_stopword_file=/var/lib/mysql/stopwords.txt
Run Code Online (Sandbox Code Playgroud)

最后,重启mysql

service mysql restart
Run Code Online (Sandbox Code Playgroud)

如果您已经有任何FULLTEXT索引的表,则必须删除这些FULLTEXT索引并再次创建它们.

绕过选项2)重新编译源代码

文件名是storage/myisam/ft_static.c.只需改变容纳600多个单词的C结构,使其为空.玩得开心重新编译!

现在FULLTEXT配置已经固化,这是另一个需要考虑的主要方面:

编写适当的重构查询,以便MySQL查询优化器正常工作!

我现在提到的内容实际上没有记录:每当执行执行JOIN的查询并且WHERE子句包含用于FULLTEXT搜索的MATCH函数时,它往往会导致MySQL查询优化器在查询时将查询视为全表扫描在FULLTEXT索引中调用的列.如果您计划使用FULLTEXT索引查询表,请始终重构您的查询以使FULLTEXT搜索仅返回子查询中的键,并将这些键连接到主表.否则,FULLTEXT索引将使MySQL查询优化器陷入混乱.

  • 选项二出于很多原因并不是一个好主意,其中最重要的原因是在推荐的过程之后,您将运行自定义的,不可升级的Mysql版本. (2认同)