Search code examples
phpmysqlfull-text-indexing

MySQL fulltext index query does not use any index?


I have a simple table created like this

CREATE TABLE IF NOT EXISTS metadata (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    title varchar(500),
    category varchar(50),
    uuid varchar(20),
    FULLTEXT(title, category)
) ENGINE=InnoDB;

When I execute a fulltext search, it took 2.5s with 1M rows. So I execute a query planner and it does not use any index:

mysql> explain SELECT uuid, title, category, MATCH(title, category) AGAINST ('grimm' IN NATURAL LANGUAGE MODE) AS score FROM metadata HAVING score > 0 limit 20;
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+----------+-------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+----------+-------+
|  1 | SIMPLE      | metadata | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1036202 |   100.00 | NULL  |
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+----------+-------+

Is that expected? How can I speed this up?


Solution

  • Your query fetches every row in the table, calculates the natural language match, and then passes the results (still for every row) to the HAVING clause. This is a table-scan.

    You should try putting the fulltext-indexed search into the WHERE clause instead, to reduce the number of matching rows.

    mysql> explain SELECT uuid, title, category FROM metadata 
        WHERE MATCH(title, category) AGAINST ('grimm' IN NATURAL LANGUAGE MODE) 
        LIMIT 20;