使用多个索引进行全文搜索

bob*_*obo 3 mysql index full-text-search

我有一个包含几列的表格,例如a, b, cd应该是可搜索的。当我需要a, b, c单独搜索d(反之亦然)时,问题就出现了。AFAIK,没有办法在所有列上使用一个复合全文索引来实现这一点,所以我创建了两个单独的索引,如下所示:

CREATE FULLTEXT INDEX idx1 ON content (a, b, c);
CREATE FULLTEXT INDEX idx2 ON content (d);
Run Code Online (Sandbox Code Playgroud)

现在我可以成功搜索第一个和第二个。对于他们两个,我将使用以下命令:

SELECT * FROM content 
WHERE MATCH(a, b, c) AGAINST ('keyword')
AND MATCH(d) AGAINST ('keyword');
Run Code Online (Sandbox Code Playgroud)

explain 告诉我这个:

+----+-------------+---------+----------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type     | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+----------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | content | fulltext | idx1,idx2     | idx1 | 0       |      |    1 | Using where |
+----+-------------+---------+----------+---------------+------+---------+------+------+-------------+
Run Code Online (Sandbox Code Playgroud)

伟大的!因此,它是用两个指标,但只返回行,其中keyword是存在于包容,我需要任何一个,所以我改变ANDOR现在解释说:

+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | content | ALL  | NULL          | NULL | NULL    | NULL |  128 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
Run Code Online (Sandbox Code Playgroud)

什么?突然间,它正在做全表扫描。为什么会这样?避免这种情况的最佳方法是什么?

Rol*_*DBA 5

不幸的是,这就是 MySQL Query Optimizer 处理 FULLTEXT 索引的方式。当MATCH子句是 中的唯一子句时WHERE,将使用索引。与 结合使用时AND,索引很容易被忽略。

我之前在Mysql全文搜索my.cnf优化中写过这种行为

建议:将查询重写为两个 FULLTEXT 搜索的并集

SELECT * FROM content 
WHERE MATCH(a, b, c) AGAINST ('keyword')
UNION
SELECT * FROM content 
WHERE MATCH(d) AGAINST ('keyword');
Run Code Online (Sandbox Code Playgroud)

试一试 !!!