Full-Text Search
Full-text search finds rows containing words or phrases in text columns, ranked by relevance, using a FULLTEXT index (InnoDB and MyISAM).
Concept
Full-text search finds rows containing words or phrases in text columns, ranked by relevance, using a FULLTEXT index (InnoDB and MyISAM). Queries use MATCH (cols) AGAINST ('terms' [mode]) in natural-language, boolean, or query-expansion mode. The built-in ngram parser supports Chinese, Japanese, and Korean text.
Why It Matters
LIKE '%word%' cannot use normal indexes and does not rank results. Full-text indexes make keyword search over defect reports, test logs, knowledge-base articles, and product descriptions fast.
Syntax
CREATE FULLTEXT INDEX ft_name ON tbl (col1, col2) [WITH PARSER ngram];
SELECT ... WHERE MATCH (col1, col2) AGAINST ('search terms' [IN NATURAL LANGUAGE MODE | IN BOOLEAN MODE | WITH QUERY EXPANSION]);Example
Key rules (InnoDB):
Minimum indexed word length innodb_ft_min_token_size = 3 (words like "V" or "Nm" are not indexed); maximum 84.
A default stopword list excludes common words ("the", "and"); custom lists via innodb_ft_server_stopword_table.
Natural-language mode ignores words that appear in 50% or more of rows only for MyISAM; InnoDB ranks with a TF-IDF-style algorithm.
The MATCH column list must exactly match a FULLTEXT index's columns.
After changing token-size or stopword settings, rebuild the index.
CREATE TABLE defect_reports (
defect_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
description TEXT NOT NULL,
FULLTEXT INDEX ft_defects (title, description)
) ENGINE = InnoDB;
INSERT INTO defect_reports (title, description) VALUES
('Regen braking torque exceeds limit', 'During HIL test TC-VCU-002 regen torque reached 270 Nm above the 250 Nm limit.'),
('BMS cell overvoltage not detected', 'Cell voltage 4.31 V was not flagged; overvoltage protection failed on BMS 2.3.1.'),
('CAN frame loss on VCU_Status', 'Frame loss of 5 percent observed on PT-CAN during vehicle test.'),
('Door ajar switch intermittent', 'BCM reports B1234 intermittently when driver door is closed.');
-- Natural language mode (ranked)
SELECT defect_id, title,
ROUND(MATCH (title, description) AGAINST ('overvoltage protection'), 4) AS score
FROM defect_reports
WHERE MATCH (title, description) AGAINST ('overvoltage protection')
ORDER BY score DESC;
-- returns defect 2 only (the only row containing those words)
-- Boolean mode: + required, - excluded, * prefix wildcard, "phrase"
SELECT defect_id, title FROM defect_reports
WHERE MATCH (title, descriptio
…CREATE FULLTEXT INDEX ft_title_ngram ON articles (title) WITH PARSER ngram; -- ngram_token_size default 2Expected Result
(BCM in defect 4 is a different word; BMS has 3 characters so it is indexed.)
SELECT defect_id, title FROM defect_reports
WHERE MATCH (title, description) AGAINST ('BMS' IN BOOLEAN MODE);+-----------+------------------------------------+
| defect_id | title |
+-----------+------------------------------------+
| 2 | BMS cell overvoltage not detected |
+-----------+------------------------------------+Common Mistakes
Searching for words shorter than the minimum token size.
MATCH column list not matching the index.
Expecting LIKE-style substring matching (full-text matches words and prefixes, not arbitrary substrings).
Using full-text for very high-volume search where a dedicated engine (Elasticsearch/OpenSearch) is more suitable.
Best Practices
Use boolean mode for user-facing search boxes with explicit operators.
Tune token size and stopwords for technical vocabularies (codes like "ECU", "DTC").
Combine with normal filters (AND status = 'OPEN').
Interview Relevance
Low-medium: "How do you implement search in MySQL?", "Natural vs boolean mode?", "Why doesn't my full-text search find short words?".
Practice Questions
Search defect reports containing "CAN" but not "loss".
Explain why searching "V" finds nothing.
Rank reports for the query "test limit".