跳转至

ES 倒排索引:为何擅长全文检索


正排索引 vs 倒排索引

flowchart LR
    subgraph "正排索引(传统数据库)"
        D1["文档1: Java是最好的语言"]
        D2["文档2: Java性能很强"]
        D3["文档3: Python也很好"]
        Q1["查询: Java"] -->|全表扫描 O(n)| D1
        Q1 -->|全表扫描 O(n)| D2
        Q1 -->|全表扫描 O(n)| D3
    end

    subgraph "倒排索引(ES)"
        T1["词项: Java"] --> DL1["→ 文档1(位置0), 文档2(位置0)"]
        T2["词项: 性能"] --> DL2["→ 文档2(位置1)"]
        T3["词项: Python"] --> DL3["→ 文档3(位置0)"]
        Q2["查询: Java"] -->|哈希查找 O(1)| T1
    end

倒排索引构建过程

flowchart LR
    A["原始文档\n'Java是最好的语言'"] --> B["分词器\nAnalyzer"]
    B --> C["分词结果\n[Java, 最好, 语言]"]
    C --> D["标准化\n小写/去停用词"]
    D --> E["词项词典\nTerm Dictionary"]
    E --> F["倒排列表\nPosting List\n文档ID + 位置 + 频率"]

为什么比 LIKE 快几个数量级

  • LIKE '%Java%':逐行扫描每条记录,时间复杂度 O(n),百万数据需要数秒
  • 倒排索引:直接通过词项哈希定位文档列表,时间复杂度 O(1),百万数据只需毫秒
  • 本质区别:LIKE 是"从记录找词",倒排索引是"从词找记录"

面试题:ES 的倒排索引和 MySQL 的 B+ 树索引有什么区别?

  • B+ 树:适合精确查询、范围查询,按字段值排序存储,支持前缀匹配
  • 倒排索引:适合全文检索,按词项存储文档列表,支持分词后的任意词项查找
  • 本质区别:B+ 树是"从记录找字段值",倒排索引是"从词项找记录"