全文索引对TEXT字段查得慢且搜不到关键词,是因为默认ft_min_word_len=4导致短词如“AI”被过滤;需调整该值并重建索引,但过小会增大索引体积、引入停用词;B-tree前缀索引无法优化LIKE '%xxx%';虚拟列哈希可加速等值查询;SELECT *拉取大字段才是真瓶颈。

为什么全文索引对 TEXT 字段查得慢还搜不到关键词
因为默认 ft_min_word_len=4,像 “AI”、“go”、“API” 这类常见词直接被过滤掉,你搜了也匹配不上。哪怕建了 FULLTEXT(content),只要关键词短于 4 字符,就进不了倒排索引。
实操建议:
- 先确认当前值:
SHOW VARIABLES LIKE 'ft_min_word_len'; - 若业务需要搜短词,改配置(需重启或动态设置):
SET GLOBAL ft_min_word_len = 2;,再重建索引:ALTER TABLE articles DROP INDEX ft_content, ADD FULLTEXT(content); - 注意:设太小会显著增大索引体积、拖慢插入,并可能引入大量无意义停用词(如 “a”、“to”),
ft_stopword_file可自定义但 MySQL 8.0 默认停用词表不可删减 - 字段必须是
CHAR/VARCHAR/TEXT,BLOB或 JSON 类型不支持全文索引
前缀索引根本没法加速 LIKE '%xxx' 查询
LIKE '%xxx' 或 LIKE '%xxx%' 永远不会用上 B-tree 前缀索引——这是结构决定的,不是长度没设对。MySQL 只能从左往右匹配,% 开头等于放弃索引。
实操建议:
- 别给
content加INDEX(content(100))试图优化模糊中间匹配,它只对WHERE content LIKE 'xxx%'有效 - 真要支持任意位置关键词,优先抽关键信息:比如日志里常含 “error code: 500”,就加字段
error_code VARCHAR(32)并建普通索引 - 若必须全文扫描式搜索,用
MATCH(content) AGAINST('xxx' IN NATURAL LANGUAGE MODE),但注意它不支持布尔操作符,且返回相关性排序而非精确匹配 - 高频模糊查场景,别硬扛,换 Elasticsearch 或 Meilisearch —— 它们专为这类查询设计,MySQL 不是搜索引擎
虚拟列哈希 + 索引能绕过溢出页读取
当你要按内容做等值判断(比如“这条日志是否已存在”),又不想每次 SELECT 都触发大字段 I/O,虚拟列是轻量级解法。它让 MySQL 在写入时自动算哈希,查询走索引,完全避开读溢出页。
将 LaTeX(.tex)学术论文转换为 Word(.docx),支持可编辑的 OMML 公式、原生 Word 表格、嵌入图形、IEEE 双栏排版及参考文献
实操建议:
- 加虚拟列:
ALTER TABLE logs ADD COLUMN content_md5 CHAR(32) AS (MD5(content)) STORED; - 建索引:
CREATE INDEX idx_content_md5 ON logs(content_md5); - 查询写法:
SELECT * FROM logs WHERE content_md5 = MD5('xxx') AND content = 'xxx';(后半段防哈希碰撞,不能省) - 注意:MD5 是 32 字符十六进制,字段类型必须是
CHAR(32);如果内容超长,MD5()函数本身性能尚可,但别在 WHERE 里反复调用MD5(content),会失去索引能力 - 不适用于模糊匹配或范围查询,纯等值场景才高效
真正慢的从来不是索引,而是 SELECT * 拉大字段
EXPLAIN 显示 type=ALL、rows=10000,但 Rows_sent=10,说明 MySQL 扫了全表,却只为返回 10 行的元数据——而每行都强制加载了几 MB 的 content,IO 和内存全耗在这上面。
实操建议:
- 永远显式列出字段:
SELECT id, title, created_at FROM articles,而不是SELECT * - ORM 用户尤其注意:Hibernate/JPA 默认 eager load、Django ORM 的
select_related可能隐式拉取大字段,关掉或改用defer('content')/lazy=True - 如果前端需要预览,拆成两步:列表页查元数据,详情页再单独
SELECT content FROM articles WHERE id = ? - 监控重点看
Buffer pool hit rate是否骤降 —— 如果缓存命中率跌到 90% 以下,基本就是大字段在污染 buffer pool
真实瓶颈不在怎么搜,而在要不要把几 MB 文本塞进数据库。一旦开始纠结“如何让 LIKE '%xxx%' 快一点”,往往说明架构已偏离合理边界。

















