Reputation: 23581
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?
Upvotes: 3
Views: 844
Reputation: 562871
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;
Upvotes: 3