傳統 LIKE '%keyword%' 查詢在大數據量下效能極差,且無法支援語意相關度排序。MySQL 內建的 全文索引 專為自然語言搜尋設計,支援布林模式、相關度評分與停用詞過濾,是中小型專案實現全文檢索的輕量化首選。
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title, body)
) ENGINE=MyISAM;
ALTER TABLE articles ADD FULLTEXT INDEX ft_title_body (title, body);
SELECT * FROM articles
WHERE MATCH(title, body) AGAINST('database');
特性:自動按相關度降序排列;忽略大小寫;若關鍵字出現在超過 50% 記錄中,視為停用詞而不回傳結果。
SELECT id, MATCH(title, body) AGAINST('Tutorial') AS relevance
FROM articles;
SELECT id, body,
MATCH(title, body) AGAINST('Security implications of running MySQL as root') AS score
FROM articles
WHERE MATCH(title, body) AGAINST('Security implications of running MySQL as root');
MySQL 優化器會合併兩次相同的 MATCH(),僅執行一次全文搜尋,無額外開銷。
透過 IN BOOLEAN MODE 修飾詞啟用,不受 50% 門檻限制,且不自動按相關度排序。
SELECT * FROM articles
WHERE MATCH(title, body) AGAINST('+MySQL -YourSQL' IN BOOLEAN MODE);
| 運算子 | 含義 | 範例 |
|---|---|---|
+ | 必須包含 | +apple +juice |
- | 必須不包含 | +apple -macintosh |
> / < | 增加/降低基準相關度 | +apple >pie |
() | 分組 | +apple +(>pie <strudel) |
~ | 負向貢獻(噪聲詞) | +apple ~macintosh |
* | 截斷符(僅能置後) | apple* |
"..." | 片語精確匹配 | "some words" |
MATCH() 參數必須來自同一張表,且須完全符合某個 FULLTEXT 索引的欄位組合(布林模式除外)。AGAINST() 參數必須為常數字串,不可使用變數或欄位。ft_min_word_len 控制),中文環境需配合分詞器或調整參數。ft_stopword_file 自訂。SET GLOBAL ft_min_word_len=2; -- 需重建索引生效
建立文字檔列出停用詞,設定 ft_stopword_file=/path/stopwords.txt 並重啟 MySQL、重建索引。
修改原始碼 myisam/ftdefs.h:#define GWS_IN_USE GWS_FREQ 並重新編譯 MySQL。警告:會嚴重降低相關度判準確度,建議改用布林模式。
REPAIR TABLE tbl_name QUICK;
MySQL 全文索引雖不及 Elasticsearch 功能豐富,但在中小型應用、單機部署、維運成本敏感的場景下極具性價比。掌握自然語言與布林兩大模式、善用相關度分數、根據業務調整詞長與停用詞,即能以最低成本提供優質搜尋體驗。