对MySQL 5.7版本的全文搜索做一翻测试后,觉得有非常大的改进,因此更新了一下全文搜索插件,推出了MySQL 5.7的版本。并从某热心网友处得到了8百万条论坛贴子记录用来做测试。综合测试下来,觉得完全可以用来做中小型网站商品数据的全文搜索解决方案,从安装布署的角度来讲非常地省心。
mysql> select count(*) from `pre_forum_post_7`; +----------+ | count(*) | +----------+ | 8879422 | +----------+ 1 row in set (1.96 sec)
从表结构中看出,有两个字段需要用来做全文搜索,分别是贴子的主题字段(“subject”)和正文(“message”)字段。
mysql> desc `pre_forum_post_7`; +-------------+-----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+-----------------------+------+-----+---------+-------+ ...... | subject | varchar(80) | NO | MUL | | | | message | mediumtext | NO | MUL | NULL | | ...... +-------------+-----------------------+------+-----+---------+-------+ 25 rows in set (0.00 sec)
接下来就在这两个字段上创建全文过经引,请观察一下创建索引的速度还是比较不错的。
mysql> create fulltext index `idx_post_7_all` -> on `pre_forum_post_7`(subject, message) with parser friso; Query OK, 0 rows affected (7 min 27.46 sec) Records: 0 Duplicates: 0 Warnings: 0
后来注意到自己写的全文搜索插件只会索引前1024个字节里的内容,统计了一下正文的平均长度后,觉得需要调 大一些,运行以下命令来将最大的分析长度调整到64KB。
mysql> show variables like 'friso%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | friso_doc_length | 1024 | | friso_exact_word | 1 | | friso_word_length | 3 | +-------------------+-------+ 3 rows in set (0.00 sec) mysql> set global friso_doc_length=65536; Query OK, 0 rows affected (0.00 sec)
然后删除原来创建的全文索引进行重建。
mysql> alter table `pre_forum_post_7` drop index `idx_post_7_all`; Query OK, 0 rows affected (0.17 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> create fulltext index `idx_post_7_all` -> on `pre_forum_post_7`(subject, message) with parser friso; Query OK, 0 rows affected (11 min 20.11 sec) Records: 0 Duplicates: 0 Warnings: 0
创建索引所需的时间比原来长了50%,但仍然比较快。接下来就可以执行全文搜索的SQL语句了,下面是查询两个非常普通的中文词语的结果,可以看到性能相当地不错(与给我们测试数据的网友进行了交流后得出此结论)。
mysql> select count(*) from `pre_forum_post_6` -> where match(subject,message) against ('苹果'); +----------+ | count(*) | +----------+ | 29200 | +----------+ 1 row in set (0.06 sec) mysql> select count(*) from `pre_forum_post_6` -> where match(subject,message) against ('阿里巴巴'); +----------+ | count(*) | +----------+ | 489 | +----------+ 1 row in set (0.00 sec)
也可以使用压测工具进行更强的性能测试,采用MySQL来做全文搜索时,如果单个节点的并发处理能力不够,可以很快地搭建多个备库,并可布署OneProxy来做负载均衡,以提升系统的全文搜索能力。