Qua*_*kle 2 mysql full-text-search
我想知道为什么我的全文搜索没有返回任何结果。对我来说,这似乎很简单,但可惜它不起作用。我离 DBA 很远,但是查看 EXPLAINed 查询,我看到的key_len
是零,这似乎很奇怪。
我正在运行 MySQL 5.5.41
创建表
CREATE TABLE `searchable_content` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`page_id` int(11) DEFAULT NULL,
`menu_title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`content` text COLLATE utf8_unicode_ci,
PRIMARY KEY (`id`),
FULLTEXT KEY `menu_title` (`menu_title`),
FULLTEXT KEY `title` (`title`),
FULLTEXT KEY `content` (`content`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Run Code Online (Sandbox Code Playgroud)
表格内容
+----+---------+------------+-------+------------------------------------------------+
| id | page_id | menu_title | title | content |
+----+---------+------------+-------+------------------------------------------------+
| 8 | 42 | Apps | Apps | <p>blah blah blah blah blabbity blah blah</p> |
+----+---------+------------+-------+------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
询问
SELECT
page_id,
MATCH(`content`) AGAINST ('blabbity') AS 'relevance'
FROM
`searchable_content`
WHERE
MATCH(`content`) AGAINST ('blabbity');
Run Code Online (Sandbox Code Playgroud)
该查询已解释
+----+-------------+--------------------+----------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------+----------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | searchable_content | fulltext | content | content | 0 | | 1 | Using where |
+----+-------------+--------------------+----------+---------------+---------+---------+------+------+-------------+
Run Code Online (Sandbox Code Playgroud)
首先,忽略key_len
解释,该值仅在 BTREE 索引的上下文中有意义,因此FULLTEXT
无论索引/列的实际大小如何,扫描时它始终为 0 。
其次,默认情况下,FULLTEXT 索引在“自然语言模式”下使用,正如它所记录的那样,它将忽略出现在 50% 或更多行中的结果(“出现在 50% 或更多行中的词”行被认为是常见的并且不匹配。”)。由于您只有 1 行,因此您将始终获得 0 个结果。请注意,如果再添加 2 条不匹配的记录,您将获得所需的结果:
mysql> insert into searchable_content () VALUES ();
Query OK, 1 row affected (0.00 sec)
mysql> insert into searchable_content () VALUES ();
Query OK, 1 row affected (0.00 sec)
mysql> SELECT
page_id,
MATCH(`content`) AGAINST ('blabbity') AS 'relevance'
FROM
`searchable_content` WHERE
MATCH(`content`) AGAINST ('blabbity');
+---------+--------------------+
| page_id | relevance |
+---------+--------------------+
| 42 | 0.3573872447013855 |
+---------+--------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
如果您可能想获得所有结果,而不管匹配的百分比如何,我建议您使用布尔模式:
mysql> SELECT
page_id,
MATCH(`content`) AGAINST ('+blabbity' IN BOOLEAN MODE) AS 'relevance'
FROM
`searchable_content`
WHERE MATCH(`content`) AGAINST ('+blabbity' IN BOOLEAN MODE);
+---------+-----------+
| page_id | relevance |
+---------+-----------+
| 42 | 1 |
+---------+-----------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
虽然你失去了排名。小心,因为你永远不会匹配短于ft_min_word_len
(innodb_ft_min_token_size
对于 InnoDB) 的单词。更改此变量可能需要重新创建索引。
另请注意,您可以使用单个索引同时搜索三列。
最后但并非最不重要的一点是,从 MySQL 5.6 开始,InnoDB 可以使用全文搜索,5.6 和 5.7 都在性能方面带来了一些有趣的改进。如果您需要更灵活、功能更完整或性能更高的搜索解决方案,则必须使用外部工具,如 Sphinx 或 Lucene。
归档时间: |
|
查看次数: |
5630 次 |
最近记录: |