MySQL 內建全文索引**不支援中文分詞**,將中文視為單一詞元,導致 `MATCH...AGAINST` 無法正確匹配中文關鍵字。`mysqlcft` 是基於 C++ 開發的解析器插件,支援中文分詞,讓 MySQL 原生全文索引具備中文搜尋能力。
[mysqld]
ft_min_word_len = 1 -- 預設 4,中文單字多為 1-2 字,必須改為 1
修改後**重啟 MySQL** 生效。
mysql> SHOW VARIABLES LIKE 'plugin_dir';
+---------------+---------------------------+
| Variable_name | Value |
+---------------+---------------------------+
| plugin_dir | /usr/lib/mysql/plugin/ |
+---------------+---------------------------+
https://code.google.com/archive/p/mysqlcft/ (或 GitHub 鏡像)cp mysqlcft.so /usr/lib/mysql/plugin/
chown mysql:mysql /usr/lib/mysql/plugin/mysqlcft.so
chmod 755 /usr/lib/mysql/plugin/mysqlcft.so
mysql> INSTALL PLUGIN mysqlcft SONAME 'mysqlcft.so';
Query OK, 0 rows affected (0.01 sec)
mysql> SHOW PLUGINS;
+-----------+----------+----------------+---------+---------+
| Name | Status | Type | Library | License |
+-----------+----------+----------------+---------+---------+
| mysqlcft | ACTIVE | FTPARSER | mysqlcft.so | GPL |
+-----------+----------+----------------+---------+---------+
**Status = ACTIVE、Type = FTPARSER** 表示安裝成功。
ALTER IGNORE TABLE `db_name`.`table_name`
ADD FULLTEXT INDEX `idx_title` (`title`) WITH PARSER mysqlcft;
ALTER IGNORE TABLE `db_name`.`table_name`
ADD FULLTEXT INDEX `idx_title_content` (`title`, `content`) WITH PARSER mysqlcft;
SELECT * FROM `table_name`
WHERE MATCH(`title`) AGAINST('北京' IN NATURAL LANGUAGE MODE);
-- 必須包含「北京」
SELECT * FROM `table_name`
WHERE MATCH(`title`) AGAINST('+北京' IN BOOLEAN MODE);
-- 包含「北京」但不包含「上海」
SELECT * FROM `table_name`
WHERE MATCH(`title`) AGAINST('+北京 -上海' IN BOOLEAN MODE);
-- 通配符搜尋 (以「北」開頭)
SELECT * FROM `table_name`
WHERE MATCH(`title`) AGAINST('北*' IN BOOLEAN MODE);
| 運算符 | 含義 | 範例 |
|---|---|---|
| + | 必須包含 | +北京 |
| - | 必須不包含 | -上海 |
| * | 通配符 (僅尾部) | 北* |
| " | 精確短語 | "北京市" |
| () | 分組 | +(北京 上海) -廣州 |
| ~ | 降低相關性 | ~北京 |
-- 1. 先刪除所有使用 mysqlcft 的全文索引
DROP INDEX `idx_title` ON `db_name`.`table_name`;
-- 2. 卸載插件
UNINSTALL PLUGIN mysqlcft;
| 項目 | 說明 |
|---|---|
| 索引大小 | 約原文 2-3 倍 (分詞後詞元增加) |
| 寫入效能 | INSERT/UPDATE 稍慢 (需分詞建索引) |
| 查詢效能 | 百萬級資料 < 100ms (有索引支援) |
| 分詞準確度 | 基於詞典,專業術語/新詞可能需自定義詞典 |
| 不支援功能 | ngram 模式、拼音搜尋、同義詞擴展 |
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| mysqlcft 插件 | 原生 SQL、零架構依賴、輕量 | 分詞準確度有限、無拼音/同義詞、維護停滯 | 中小型專案、簡單中文搜尋、不想引入外部服務 |
| MySQL 5.7+ 內建 ngram parser | 官方支援、無需編譯、支援中日韓 | 基於 n-gram 非語義分詞、索引大、精確度一般 | MySQL 5.7+、不想編譯插件、接受 n-gram 特性 |
| Elasticsearch + IK 分詞器 | 專業搜尋引擎、語義分詞、同義詞、高亮、聚合 | 架構複雜、需同步資料、運維成本高 | 大型應用、複雜搜尋需求、推薦/聚合分析 |
| Sphinx / Manticore Search | 專為 SQL 設計、增量索引、支援中文分詞 | 需額外部署、查詢語法非標準 SQL | 傳統 PHP/Java 專案、需高效能全文搜尋 |
[mysqld]
ngram_token_size = 2 -- 2-gram,預設 2,可設 1-10
-- 建立索引
ALTER TABLE `table` ADD FULLTEXT INDEX `idx_content` (`content`) WITH PARSER ngram;
-- 查詢 (自然語言模式)
SELECT * FROM `table` WHERE MATCH(`content`) AGAINST('北京' IN NATURAL LANGUAGE MODE);
若專案可升級至 MySQL 5.7+,**強烈建議優先使用內建 ngram parser**,免去編譯相容性問題,官方長期維護更有保障。mysqlcft 適合舊版本 MySQL (5.1/5.5/5.6) 且無法升級的存量系統維護場景。