Search :: 可以使用MySQL 5.7来做网站上千万商品记录的全文搜索问题!

对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来做负载均衡,以提升系统的全文搜索能力。