为什么 MySQL 的 LIKE 慢如蜗牛,而 ES 快如闪电?
如果说是一个老老实实、按部就班的**“图书管理员”“速记员”**。当你在几亿条数据中搜索一个词时,MySQL 需要把所有数据(全表扫描)。而 ES 只需要,就能直接告诉你答案。这个“关键词表”,在技术上就叫做。它是所有搜索引擎(Google, Baidu, ES, Lucene)的核心基石。

如果说 MySQL 是一个老老实实、按部就班的**“图书管理员”,那么 Elasticsearch (ES) 就是一个开了天眼的“速记员”**。
当你在几亿条数据中搜索一个词时,MySQL 需要把所有数据从头到尾看一遍(全表扫描)。
而 ES 只需要看一眼书后的“关键词表”,就能直接告诉你答案。
这个“关键词表”,在技术上就叫做 倒排索引。它是所有搜索引擎(Google, Baidu, ES, Lucene)的核心基石。
💻 一、技术分析:把世界颠倒过来
要理解“倒排”,我们先得理解什么是“正排”。
1. 正排索引 (Forward Index) —— MySQL 的做法
这是我们最直观的存储方式:以文档为核心,记录文档里有什么词。
| 文档 ID (DocID) | 文档内容 (Content) |
|---|---|
| 1 | 谷歌地图 (Google Map) |
| 2 | 谷歌搜索 (Google Search) |
- 怎么查? 如果你要查“搜索”这个词。
- 过程: 系统必须先看 ID=1,发现没有;再看 ID=2,发现有。
- 代价: 数据越多,遍历越慢。复杂度 O(N)。
2. 倒排索引 (Inverted Index) —— 搜索引擎的做法
这是反直觉的存储方式:以词为核心,记录哪些文档包含这个词。
为了做这个,系统在存数据时会先进行 分词 (Tokenization),把句子拆碎,然后建立一张新表:
| 关键词 (Term) | 倒排表 / 出现位置 (Posting List) |
|---|---|
| 谷歌 | [1, 2] |
| 地图 | [1] |
| 搜索 | [2] |
- 怎么查? 如果你要查“搜索”这个词。
- 过程:
- 系统直接去左边找“搜索”。
- 瞬间找到,后面挂着 ID
[2]。 - 直接返回文档 2。
- 代价: 无论你有 100 条还是 100 亿条数据,查找速度几乎是一样的(取决于词典的大小,通常用哈希或 B+ 树优化)。复杂度接近 O(1)。
3. 倒排表里还有啥?
实际上,右边的倒排表 (Posting List) 不仅仅存了文档 ID,通常还会存:
- 词频 (TF): 这个词在这篇文章里出现了几次?(用于算相关性打分,决定谁排前面)。
- 位置 (Position): 这个词在文章的第几个位置?(用于短语搜索,比如搜 “Google Map”,系统知道这两个词必须挨在一起)。
📖 二、故事场景:图书馆的“笨办法”与“聪明办法”
为了搞懂为什么它叫“倒排”,我们将 数据库 比作 一座巨大的图书馆。
1. 正排索引 —— “笨管理员” (MySQL)
- 场景: 你走进图书馆,问管理员:“我想找一本关于**‘哈利波特’**的书。”
- 做法: 管理员非常敬业。他从第 1 个书架的第 1 本书开始拿起,翻开看有没有“哈利波特”这几个字。看完放回去,再拿第 2 本……
- 结果: 等他翻完 100 万本书,你也老了。这就是
LIKE '%哈利波特%'。
2. 倒排索引 —— “索引卡片” (Elasticsearch)
-
场景: 这次你去了隔壁的现代化图书馆。
-
准备工作 (建立索引):
-
只要有新书入库,管理员先不急着上架。
-
他先读一遍书,把里面的关键词提取出来:“哈利波特”、“魔法”、“罗琳”。
-
他在墙上的索引卡片箱里,找到“哈利波特”这张卡片,在后面写上:这本书在 3 号架 5 层。
-
搜索过程:
-
你问:“找**‘哈利波特’**”。
-
管理员直接走到卡片箱,抽出“哈利波特”的卡片。
-
卡片上写着:
[Book ID: 1024, 8848]。 -
管理员直接走过去把这两本书拿给了你。
-
结果: 耗时 1 秒。
🥊 三、优缺点权衡
既然倒排索引这么快,为什么 MySQL 不全改成这样?
-
优点:
-
查询极快: 专门为“搜索”设计。
-
支持复杂搜索: 模糊搜、分词搜、同义词搜(搜“手机”能出“iPhone”)。
-
缺点:
-
写入慢: 每次存数据,都要分词、重新排列、更新索引表。这比直接把数据丢进硬盘要麻烦得多。
-
空间大: 索引文件有时候比数据本身还要大。
-
不实时: ES 通常有 1 秒左右的延迟(NRT),因为建索引需要时间;而 MySQL 写入成功就能立刻查到。
架构师的日常:
- MySQL: 负责“存”和“事务”(订单、支付)。
- Elasticsearch: 负责“搜”(商品搜索、日志分析)。
- 同步: 把 MySQL 的数据同步一份到 ES 里,专门用来给用户搜。
更多推荐

所有评论(0)