MySQL 的 LIKE '%xxx%' 性能差是因为前导通配符使 B+ 树索引失效,只能全表扫描;FULLTEXT 和内置函数同样有局限;高阶模糊需求应引入 Elasticsearch,通过 trigram、pinyin 分析器等策略实现高效文本检索。
为什么 MySQL 的
查不出性能?
因为前导通配符(
在开头)会让 MySQL 完全无法使用 B+ 树索引,只能全表扫描。哪怕加了普通索引,
也基本等于放弃索引——这是底层存储结构决定的,不是配置能绕过的。
常见误区是以为“加了索引就快”,但索引只对
有效;对
或
,索引形同虚设。
百万级数据下,
查询可能从毫秒级升到秒级甚至超时
索引虽可缓解,但仅支持自然语言模式或布尔模式,不支持任意子串、大小写敏感控制、拼音模糊等场景
内置函数如
、
同样无法走索引,纯 CPU 匹配,数据量大时更慢
什么时候该切到 Elasticsearch?
当你的模糊查询需求开始出现这些信号,就该考虑异构:多字段联合检索(比如“部门名+人名+标签”一起搜)、支持拼音/分词/同义词、需要高亮、要求亚秒级响应、或者已有分库分表导致跨库
成本极高。
以通讯录系统为例:人员信息分散在 12 个分库,每个库有
、
、
三张表,想查“北京研发部带‘AI’标签的张*”,用 MySQL 拼 SQL 几乎不可维护,而 ES 只需一条
查询。
ES 不是替代 MySQL,而是补足它不擅长的“文本即服务”能力
同步延迟可接受(秒级)的业务,用 binlog + canal 或 maxwell 做增量同步足够稳定
冷热分离明确的场景,比如历史归档数据只读,更适合放 ES 而非长期压 MySQL
MySQL 到 ES 的数据同步关键点
别直接用
全量灌 ES——字段映射错、类型不匹配、中文分词没配,查出来全是空结果。必须控制源头结构。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
典型坑:
是 tinyint(1),ES 自动识别成
,但业务代码传的是字符串
,查不到;又或者
字段没配
分词器,搜“张三”能出,“张”单独搜就失败。
建索引前先定义
:显式声明
字段用什么 analyzer,数值字段用
还是
同步脚本里做轻量清洗:把 MySQL 的
转成
或
,避免 ES 字段类型被污染
增量同步务必带上时间戳字段(如
),并用它驱动游标,别依赖自增 ID——分库后 ID 不连续
ES 查询怎么避免“查得到但不对”?
很多人把 MySQL 的
思维直接搬过去,写
,结果发现搜“张”不出来。ES 默认是分词检索,而
要求完整短语+顺序+邻近,不适合子串场景。
真正贴近
的是
或
,但它们性能差、易 OOM;更稳的做法是组合策略:
前缀搜索(类似
):用
查询,快且准
中缀/后缀(
或
):提前在索引时生成 trigram(3-gram)字段,查时用
打 trigram 字段
拼音容错:加
analyzer,搜“zhangsan”也能命中“张三”
必要时 fallback:ES 查不到再走 MySQL 主键回查,但得控制 fallback 比例,否则失去异构意义
trigram 不是银弹——它让存储翻 3 倍、写入变慢,但换来的是中缀搜索的可控延迟。要不要上,得看你的“模糊”到底有多模糊。
LIKE '%xxx%'%WHERE name LIKE '%abc%'LIKE 'abc%'LIKE '%abc'LIKE '%abc%'LIKE '%keyword%'FULLTEXTLOCATE()INSTR()JOINuserdepartmenttag_relmulti_matchSELECT * FROM useruser.statuslong"active"nameik_smartmappingtextkeywordlongNULL""falseupdated_atLIKEmatch_phrase: { query: "张三" }match_phraseLIKE '%xxx%'wildcardregexpLIKE 'xxx%'prefixLIKE '%xxx'LIKE '%xxx%'matchpinyin