ES v.s Milvus v.s PG

发布于:2025-07-19 ⋅ 阅读:(12) ⋅ 点赞:(0)

需求

对比三种常见系统在向量搜索和全文搜索方面的性能与功能差异:ES(内置 Lucene、提供 k-NN 插件)、Milvus(专用向量数据库)和PostgreSQL(pgvector扩展)。它们各自优势不同:Milvus 设计用于亿级向量数据的高效检索;ES 是分布式全文搜索引擎,也可通过 k-NN 插件进行高维向量近似检索;pgvector 则将向量嵌入与关系数据共存,适用于混合查询场景。

测试环境与数据集

  • 数据库版本:ES 8.17.4(docker部署,单节点)、Milvus 2.5.10(docker compose部署,standalone模式)、PostgreSQL 17.4-1+pgvector 0.7.0(Windows部署)。
  • 向量数据集:统一采用 768 维嵌入(常见 BERT/CLIP 维度)。例如,MSMARCO/BERT模型输出768维句向量,LAION图像嵌入也为 768 维。
  • 索引配置:为消除规模差异,三者均在相同硬件条件下建立索引:ES mapping 定义 dense_vector 字段(dims=768),索引类型设为 hnsw(M=32, ef_construction=100);Milvus 创建 HNSW 或 IVF_FLAT 索引(如 {“index_type”:“IVF_FLAT”,“params”:{“nlist”:1024}});PostgreSQL 使用 pgvector 插件,创建 HNSW 或 IVFFlat 索引:
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 1024);

其中,HNSW 索引可获得较高召回但构建缓慢、占用内存多,IVFFlat 提升查询速度但略损精度。

  • 基准工具:可使用开源工具 VectorDBBench、ANN-Benchmarks或自定义测试脚本。测试指标包括 Top-K 命中率(Recall)、吞吐量(QPS)与延迟等。
    Python 查询示例:
# Milvus 查询示例
from pymilvus import Collection, connections
connections.connect(alias="default", host="127.0.0.1", port="19530")
collection = Collection("my_collection")
query_vec = [0.1] * 768
results = collection.search([query_vec], "vector_field", param={"metric_type": "L2", "params": {"nprobe": 10}}, limit=5)
print([hit.id for hit in results[0]])

# PostgreSQL (pgvector) 查询示例
import psycopg2
conn = psycopg2.connect("dbname=test")
cursor = conn.cursor()
cursor.execute("SELECT id FROM items ORDER BY embedding <-> %s LIMIT 5;", (query_vec,))
print([row[0] for row in cursor.fetchall()])

# ES 查询示例
from elasticsearch import Elasticsearch
es = Elasticsearch()
body = {"size":5, "query": {"knn": {"vector_field": {"vector": query_vec, "k":5, "num_candidates":100}}}}
res = es.search(index="my_index", body=body)
print([hit["_id"] for hit in res["hits"]["hits"]])

向量检索

ES

ES 8.0及以上版本新增向量近邻检索k-nearest neighbor(kNN)search功能,示例:

{
  "settings": {
    "number_of_shards": 6,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "vector": {
          "type": "dense_vector",
          "dims": 960,             // 最高支持2048维度
          "index": true,
          "similarity": "cosine",  // 支持 cosine, dot_product, l2_norm
          "element_type": "float", // 支持 float, byte 
          "index_options": {       // hnsw 高级参数配置
            "type": "hnsw",
            "m": 16,
            "ef_construction": 100
          }
      }
    }
  }
}

向量检索支持的索引类型:

  • dense_vector:暴力搜索,存储原始向量,查询时计算目标向量与所有向量的距离(如余弦相似度、欧氏距离);无需额外索引结构,数据写入简单。查询性能随数据量线性下降,适合小规模数据(如数万条)
  • HNSW:Hierarchical Navigable Small World,基于图的近似最近邻(ANN)算法,通过多层图结构加速搜索;查询速度快(对数时间复杂度),适合大规模数据;需要额外存储索引,写入速度较慢。
  • IVF:Inverted File System,通过聚类将向量分到多个桶(Voronoi 单元),搜索时仅计算目标桶内的向量;适合超大规模数据(亿级以上);需要训练聚类中心,写入延迟较高。

参考

Milvus

Milvus的强项。

索引类型:

  • HNSW
  • IVF

参考:

  • https://milvus.io/docs/v2.0.x/build_index.md

PG

插件:pg_vector和pg_embdding,基于Faiss(向量数据库)的IVF Flat索引。

参考

  • https://zhuanlan.zhihu.com/p/4859988545

全文检索

ES

ES的强项,基于倒排索引。

中文全文检索

需要引入中文分词器:

  • IK:默认,两种颗粒度的拆分:
    • ik_smart:会做最粗粒度的拆分;
    • ik_max_word:会将文本做最细粒度的拆分;
  • smartCN:
  • HanLP:
  • jieba:

参考

  • https://zhuanlan.zhihu.com/p/13723417907

Milvus

检索+排序;使用 BM25 算法进行相关性评分;

适用于全文检索的 Collection,其 Schema 必须包括三个必要字段:

  • 唯一标识 Collection 中每个实体的主字段。
  • 一个VARCHAR 字段,用于存储原始文本文档,其enable_analyzer 属性设置为True 。这允许 Milvus 将文本标记为特定术语,以便进行函数处理。
  • 一个SPARSE_FLOAT_VECTOR 字段,预留用于存储稀疏嵌入,Milvus 将为VARCHAR 字段自动生成稀疏嵌入。

Milvus 2.5 集成高性能搜索引擎库 Tantivy,并内置 Sparse-BM25 算法,首次实现原生全文检索功能:

  • 内置基于 tantivy 构建的分词器:无需额外预处理,通过内置分词器(Analyzer)与稀疏向量提取能力,Milvus 可直接接受文本输入,自动完成分词、停用词过滤与稀疏向量提取,无需依赖外部模型(如BGE-M3等)。
  • 实时 BM25 统计:数据插入时动态更新词频(TF)与逆文档频率(IDF),确保搜索结果的实时性与准确性。
  • 混合搜索性能增强:基于近似最近邻(Approximate Nearest Neighbor,ANN)算法的稀疏向量检索,性能远超传统关键词系统,支持亿级数据毫秒级响应,同时兼容与稠密向量的混合查询。

对比:BM25和Sparse-BM25

BM25采用Sparse Vector,优势,包括但不限于:

  1. 对长上下文Query可构建图索引来加速搜索;
  2. 基于量化和WAND的drop_ratio等技术手段做近似匹配来提升性能;
  3. 统一语义检索和全文检索的表达方式,使用体验以及技术优化。

rerank使用 RRF(Reciprocal Rank Fusion) 算法:融合向量和文本检索结果,重新优化排序和权重分配,提升数据召回率和精确性。

参考:

  • https://milvus.io/docs/zh/full_text_search_with_milvus.md
  • https://milvus.io/docs/zh/full-text-search.md
  • https://zilliz.com.cn/blog/semantic-search-vs-full-text-search-which-one-should-i-choose-with-milvus-2-5
  • https://xie.infoq.cn/article/2d6c98ec75578495365680363
  • https://help.aliyun.com/zh/milvus/use-cases/full-text-retrieval-by-milvus-bm25-algorithm-and-application-of-hybrid-retrieval-to-rag-system

中文全文检索

{"type": "english"}:standard 分词器,

{"type": "chinese"}:针对中文文本,基于上下文分词并过滤非汉字字符,使用 jieba;Filter采用cnalphanumonly(仅保留汉字和字母数字)。

TODO:

  • 读、写性能(向量检索、全文检索)
  • 高可用部署的硬件需求

PG

全文检索=匹配+亲和(rank)。

可实现小规模数据量的全文检索功能。
优点:轻量级

索引类型:

  • GIN:通用倒排索引,Generalized Inverted Index,官方推荐
  • GiST:通用搜索树,Generalized Search Trees
  • RUM:https://github.com/postgrespro/rum

基本Query:

  • Simple Query:@@
    SELECT * FROM documents WHERE to_tsvector('english', content) @@ to_tsquery('search_term');
  • Phrase Search:& for AND, | for OR, and ! for NOT
    SELECT * FROM documents WHERE to_tsvector('english', content) @@ to_tsquery('word1 & word2');

高级Query:

  • Ranked Search:ts_rank
SELECT *, ts_rank(to_tsvector('english', content), to_tsquery('search_term')) AS rank
FROM documents
WHERE to_tsvector('english', content) @@ to_tsquery('search_term')
ORDER BY rank DESC;
  • Proximity Search:<->
    SELECT * FROM documents WHERE to_tsvector('english', content) @@ to_tsquery('word1 <-> word2');
  • Weighted Search:setweight
SELECT *, ts_rank_cd(setweight(to_tsvector('a', title), 'A') || setweight(to_tsvector('b', content), 'B'), to_tsquery('search_term')) AS rank
FROM documents
WHERE to_tsvector('english', content) @@ to_tsquery('search_term')
ORDER BY rank DESC;

中文全文检索

安装插件:

  • zhparser:https://github.com/amutu/zhparser,推荐,阿里云的RDS默认包含。
  • jieba:https://github.com/jaiminpan/pg_jieba、
  • PGroonga:https://github.com/pgroonga/pgroonga,star, https://blog.csdn.net/weixin_44957042/article/details/138917123

参考

对比

主要差异:

特性 ES Milvus PostgreSQL+pgvector
向量检索 支持dense_vector,但性能有限,适合小规模或简单场景 专为高维向量优化,支持GPU加速、多种索引算法,性能更强
向量索引类型 默认使用HNSW图算法(可量化为int8_hnsw或int4_hnsw)。支持精确搜索(脚本评分)。 支持多种ANNS索引:FLAT、IVF_FLAT、IVF_SQ8、IVF_PQ、HNSW、RHNSW_FLAT/SQ/PQ、ANNOY。FLAT保证100%准确率但查询缓慢。 支持HNSW和IVFFlat;默认无索引时为精确扫描。HNSW索引构建缓慢但查询精度高,IVFFlat平衡速度和内存
距离度量 支持L2、IP(内积)、余弦等(可通过脚本自定义)。 支持L2、IP等常用度量,二进制向量还支持Jaccard、Hamming等。 支持L2、IP、余弦(Cosine)等距离
向量检索精度 近似搜索,召回率依赖HNSW参数(ef、M)。一般可达到~90%以上(需要调整参数)。可使用精确脚本评分保证准确性。 FLAT索引可达100%召回;ANN索引可调nlist/nprobe以平衡速度和召回率,一般可>90%。 无索引时为精确搜索(100%召回);HNSW索引召回高但构建慢;IVF-Flat部分匹配,召回略低
检索速度(QPS/延迟) 集群优化良好。在高召回场景下吞吐量中等,延迟取决于硬件和参数。 专为大规模向量检索设计,支持GPU加速。Milvus在千维向量和大数据量场景下查询速度很高(可达数千QPS),吞吐量通常优于通用数据库。 作为通用DB,向量检索相对较慢。在类似参数下,pgvector的QPS远低于专用向量库
内存/存储占用 向量数据存储在pagecache中。支持量化(int8)来减小索引大小。HNSW索引在Lucene节点中占用额外内存。 HNSW/FLAT索引需要大量内存存储图或向量本身;IVF+PQ/SQ8索引压缩程度高,减小内存占用。总体而言,专用向量DB在索引存储上更灵活。 HNSW索引构建缓慢且占内存;IVFFlat需要存储聚类中心(lists)数据。所有向量数据以列方式存储在表中,数据量大时占用存储也较高
集群扩展性 内置分片和副本机制elastic.co。每个索引可划分多个主分片(shard),每个分片可有副本,以分布式方式扩展。成熟的集群管理和自动重平衡机制。 天生分布式架构:分离计算层与存储层,多节点协同。Milvus可自动将数据分片(Shard)分布到不同节点并在节点扩缩容时自动重平衡milvus.io。支持多数据节点和查询节点水平扩展。 PostgreSQL本身不支持自动水平分片;通常通过分区表和扩展(如Citus)实现横向扩展milvus.io。原生只有主从复制,用于高可用,但不自动负载均衡。部署运维相对简单,但大规模数据面临扩展挑战
全文检索支持 强大的倒排索引和分析器支持全文检索。默认使用BM25相关性算法,分析器丰富,适合复杂查询和高效排名。 2.5版本起,Milvus引入BM25全文索引,支持关键词和短语检索。可与向量检索结合,实现hybrid搜索。 PostgreSQL提供tsvector/tsquery全文搜索,基于倒排索引(GIN)执行关键词检索。默认相关性计算为TF-IDF风格(ts_rank),可通过扩展(如VectorChord-BM25)引入BM25排序
场景定位 全文搜索+结构化数据分析+基础向量检索 大规模向量相似性搜索+AI/ML场景

对比项解读:

  • 向量检索精度:在召回率(Recall)方面,所有系统的精确搜索(如Milvus的FLAT、PostgreSQL无索引扫描)均可达到 100%。使用近似索引时,精度取决于参数:Milvus的HNSW/IVF可通过增大nprobeef值获得高召回;ES的HNSW需要设置较高ef才能接近真实最近邻。实践中,如果要求召回≥98%,Milvus和ES都能达到,而pgvector的近似索引在高维场景中通常需要较多参数调优。
  • 检索速度(QPS/延迟):通用数据库(PostgreSQL、MongoDB、OpenSearch)在高召回向量搜索场景下吞吐量和延迟都明显落后于专用向量库。在相同召回条件下,其查询吞吐量比pgvector提供的PostgreSQL快近10倍。Milvus和其他专业库通常在大规模数据上能提供更高QPS。例如,Milvus官方示例在百万级数据上进行HNSW比较,展示出较高吞吐(云端部署时需注意资源配置)。ES查询速度介于两者之间:其优化良好的Lucene索引在中等规模下表现良好,但向量检索耗费内存和CPU,相比纯向量库略显逊色。综合而言,在大数据量和高吞吐场景下,Milvus通常表现最好,其次是ES,pgvector适合数据量中等、延迟要求不极端的场景。
  • 全文检索:
  • 内存与存储占用:向量检索一般需要大量内存。ES要求所有向量索引数据在节点的页缓存中才能高效查询,量化(Int8)可降低索引大小。Milvus的HNSW/FLAT索引需要在RAM中存储图结构或完整向量;使用IVF+PQ/SQ8等压缩索引可显著减少内存使用。PostgreSQL将向量直接存储在表中,HNSW索引占用额外内存较大;IVF索引还需要保存聚类单元的中心点数据。一般来说,专业向量库在内存管理上更灵活,但部署时需注意节点规格。
  • 系统扩展与运维:ES原生支持集群分片和副本,运维工具成熟(如ES Operator、Elastic Cloud)。Milvus也提供完整的分布式架构,可水平扩展;其自动重平衡功能在节点增减时保证负载均匀。PostgreSQL本身单节点性能优秀,但需额外方案(读写分离、Citus等)才能实现横向扩展。综合运维复杂度:Elastic、Milvus都需要管理多服务节点,Milvus配置稍复杂;PG相对简单但可扩展性较差。

结论: 综合来看,Milvus 在大规模向量检索场景中性能最佳,支持丰富索引类型和自动扩展,适合对吞吐和低延迟要求高的应用;ES 拥有成熟的全文搜索能力,适合混合结构化、文本和向量的检索(内置 BM25、倒排索引);PostgreSQL + pgvector 则为传统关系库用户提供便利,适合数据量适中、方便集成的场景,但其向量查询性能明显弱于专用向量库(多项基准显示 QPS 低于 Milvus)。选择哪种方案取决于具体需求:如果需要同时做关键词和语义搜索,ES 可快速构建混合应用;如果追求最大化向量检索性能与扩展性,Milvus 是更优选;如果已有 PostgreSQL 生态且对吞吐要求不极端,则 pgvector 提供足够的功能。

附录

Tantivy

Rust语言编写,Lucene平替,开源高性能搜索引擎库,可被集成到各种数据库中,包括:

  • Milvus
  • PG
  • MyScaleDB:针对向量搜索进行优化的ClickHouse开源分支

https://docs.rs/tantivy/latest/tantivy/
https://tantivy-search.github.io/bench/
https://github.com/dromara/MilvusPlus/blob/main/Tantivy文本匹配.md
https://www.yicaiai.com/news/article/670738554ddd79f11a6e2770
https://www.53ai.com/news/hangyeyingyong/2024053165894.html

关键功能

  • BM25相关性评分:Elasticsearch、Lucene和Solr都将BM25用作默认相关性排名算法。BM25分数评估文本搜索的准确性和相关性,增强用户搜索体验。
  • 可配置标记器:此功能支持各种语言标记器,满足用户多样化的标记化需求。
  • 自然语言查询:用户可以使用AND、OR和IN等关键字灵活地组合文本查询,降低SQL语句编写的复杂性。

ParadeDB

GitHub

ParadeDB is a full text search engine built for Postgres. Powered by an extension called pg_search, ParadeDB embeds Tantivy, a Rust-based Lucene alternative, inside Postgres.

基于pg_search+ Tantivy。

参考

  • https://iniakunhuda.medium.com/postgresql-full-text-search-a-powerful-alternative-to-elasticsearch-for-small-to-medium-d9524e001fe0
  • https://risingwave.com/blog/implementing-high-performance-full-text-search-in-postgres/

检索

包括:

  • Semantic Search:语义搜索
  • Keyword Search:关键词搜索
  • Full Text Search:FTS,全文搜索
  • Vector Search:向量搜索
  • Exact Match Search:精确搜索
  • Fuzzy Search:模糊搜索
检索类型 语义搜索 关键词搜索 全文搜索 向量搜索 精确搜索 模糊搜索
核心 理解查询的语义意图,而非字面匹配 基于精确关键词匹配(词袋模型) 对文本内容进行全面扫描和索引,支持复杂查询 将数据转换为向量,计算向量距离(如余弦相似度) 完全匹配字段值(区分大小写和格式) 容忍拼写错误或近似匹配
技术 使用NLP模型(如BERT、GPT)生成dense向量,计算语义相似度 倒排索引、TF-IDF、BM25等稀疏向量方法 分词(Tokenization)、倒排索引、支持布尔逻辑(AND/OR/NOT) DenseVector(语义搜索常用,如BERT)SparseVector(全文搜索常用,如TF-IDF) 哈希索引、B树索引 编辑距离(LevenshteinDistance)N-gram分词(如“apple”和“appel”可能匹配)
特点 能处理同义词、近义词(如“苹果”和“iPhone”)自然语言查询友好(如“如何做番茄炒蛋”) 严格匹配关键词(如搜索“Java”不会返回“Coffee”)无法处理语义扩展 支持模糊匹配、短语匹配、通配符等关键词搜索的增强版 适合非结构化数据计算开销较大 结果100%精确不支持任何模糊性 容错性强(如搜索“Misissippi”仍能匹配“Mississippi”)
应用 智能客服、知识库问答、推荐系统 传统搜索引擎、数据库查询(如SQL的LIKE 文档检索、日志分析 相似图片搜索、语义检索 数据库主键查询、验证码校验 用户输入纠错、搜索引擎的“你是不是想找”
工具 ES向量检索、FAISS、Milvus(结合语义模型) ES的全文检索、MySQL的全文索引 Elasticsearch、Solr、PostgreSQL的tsvector Milvus、FAISS、Weaviate 所有关系型数据库 ES的fuzzy查询、Redis的模糊键匹配

其他:

  • Hybrid Search:混合搜索,结合关键词搜索和向量搜索,增强搜索结果的相关性;
  • Geospatial Search:地理位置搜索,基于经纬度或地理范围,如:ES 的geo_distance、PostGIS;
  • Temporal Search:时间范围搜索,按时间戳过滤;
  • Multimodal Search:多模态搜索,跨模态检索(如用文本搜索图片,或用图片搜索文本),如CLIP等跨模态模型生成的向量。

Dense Vector v.s Sparse Vector
稠密向量和稀疏向量,向量表示的两种主要形式。

特征 Dense Vector Sparse Vector
生成 由神经网络模型生成 基于词袋模型或n-gram
维度 固定维度(通常50-1000维),每个维度都有含义但不直接可解释 极高维度(可能数万到数百万维),维度对应特定词或术语
非零值 几乎全部维度都有非零值 绝大多数维度为零值
存储 存储所有维度的值,需要较大存储空间 只存储非零值及其位置,存储空间需求小
计算 适合计算余弦相似度等度量 计算效率高(稀疏性)
语义 捕获深层次语义关系 基于词频或出现统计
典型应用 ES向量检索、语义相似度、语义搜索 Milvus全文检索、传统文本检索、关键词搜索

其他
https://db-engines.com/en/ranking/vector+dbms


网站公告

今日签到

点亮在社区的每一天
去签到