当前位置:首页>排行榜>向量数据库怎么选:Chroma / Qdrant / LanceDB 还是插件内索引

向量数据库怎么选:Chroma / Qdrant / LanceDB 还是插件内索引

  • 更新时间 2026-10-25 09:30:21
向量数据库怎么选:Chroma / Qdrant / LanceDB 还是插件内索引

把 400 块真实笔记丢给本地嵌入模型,实测 39.1 块/秒。按这个速度算完,我库里 15,558 篇要跑三小时二十八分。这个数字直接决定了我最后没装任何向量数据库。四方案对比 + 磁盘账 + 增量索引的三件事。

向量数据库怎么选:Chroma / Qdrant / LanceDB 还是插件内索引

我先给一个实测数字,再讲选型。

把 400 块从我自己库里随机抽出来的真实笔记丢给本地嵌入模型,批量 64,跑完计时:39.1 块/秒。

然后我数了一下库:15,558 篇 md,331,941,405 字,753.1 MB。按 800 字一块、120 字重叠切,是 48.8 万块。

488,000 ÷ 39.1 = 12,480 秒。三小时二十八分。

这就是"要不要单独装一个向量数据库"的起点。装之前先算这个数,能省掉一个周末。

先说结论:九成的 Obsidian 用户不需要单独装

向量数据库解决的是存和查的问题,不是有没有语义检索的问题。

你装个 Smart Connections 或者 Copilot,点一下"Build Index",语义检索就已经有了。它们自带索引,落在库里一个隐藏目录,你什么都不用配。

单独的向量数据库只在三种情况下才值得:

你的情况
需不需要单独装
库在 5000 篇以内,只在 Obsidian 里用
不需要,插件内索引够了
想在 Obsidian 之外复用同一份索引(脚本、Agent、CLI)
需要
要按 frontmatter 字段过滤(只搜某标签、某年份)
需要,插件内索引的过滤很弱
库大到索引文件塞不进内存或同步爆掉
需要
要多台机器/多个人共读同一份索引
需要,得上服务化方案

我自己属于"想在 Obsidian 之外复用",所以最后还是装了。但装的是最轻的那个,下文说。

四个方案差在哪

插件内索引
Chroma
Qdrant
LanceDB
形态
Obsidian 插件自带
进程内库 / 服务
独立服务(Rust)
进程内库,磁盘原生
要不要开端口
不开
进程内不开;服务化 8000
6333 REST + 6334 gRPC
不开
上手时间
0
5 分钟
20 分钟
5 分钟
持久化
库内隐藏目录
一个目录
一个目录 / 卷
一个目录
元数据过滤
基本没有
有
最强
有,SQL 式 where
量化压缩
无
无
四种,可省 4~32 倍内存
IVF_PQ
换模型
全量重建
重建 collection
重建 collection
维度写死,重建表
适合规模
万篇级
百万~千万向量
千万级以上
单机百万~千万
多进程/多端共享
不行
服务模式可以
可以
只读共享可以,别并发写

一句话的定位:插件能跑就别装,要复用上 LanceDB 或 Chroma 进程内,要服务化和过滤才上 Qdrant。

插件内索引:零部署,但两条硬约束

这是绝大多数人的终点,先把它的边界说清楚。

第一条:索引文件是二进制,且跟平台相关,不要同步。

Smart Connections 的索引落在库根目录的 .smart-env/。你换台机器、换个系统,这份索引大概率读不出来或者读出来是空的,插件会自己重建——那又是几小时。

正确做法:把这个目录加进同步忽略清单。Obsidian Sync 在设置里排除,Syncthing 写进 .stignore,Git 写进 .gitignore。

第二条:两个插件不共用索引。

Copilot 有自己的一套嵌入索引,Smart Connections 有另一套。都开着,就是同一批笔记向量化两遍,磁盘大约翻倍。磁盘紧张的话,二选一,或者接受这个成本。

Copilot 从 3.x 起把密钥交给 Obsidian 1.11.4 的 SecretStorage 保管,密钥不再明文躺在配置文件里——但索引本身还是两份。

Chroma:默认答案,五分钟

如果你只是想让脚本和 Obsidian 之外的工具也能查这份索引,Chroma 是最省事的。

pip install chromadb
import chromadbclient = chromadb.PersistentClient(path="./chroma_db")col = client.get_or_create_collection("notes", metadata={"hnsw:space": "cosine"})col.add(    ids=["note-001#0", "note-001#1"],    documents=["块内容……", "块内容……"],    metadatas=[{"path": "20-AI/xx.md", "tags": "RAG"},               {"path": "20-AI/xx.md", "tags": "RAG"}],)print(col.query(query_texts=["手机上改的笔记第二天没了"], n_results=5))

三个坑:

匿名遥测默认开着。 进程内用 Settings(anonymized_telemetry=False),容器用环境变量 ANONYMIZED_TELEMETRY=FALSE。这是唯一一个默认会往外发数据的选项,第一件事就是关掉。

ALLOW_RESET 默认是 false,别打开。 它控制的是"能不能通过 API 把整个库删掉"。打开了,一个误请求就归零。

Chroma 的舒适区是单节点百万到千万向量。 过了这条线 p95 会明显抬头,那时候换 Qdrant。它在 2026 年已经进 1.x 时代,Docker 镜像常见标签是 1.5.x,进程内那个 PersistentClient 的 API 这两年基本没变,教程不会过时。

底子是 SQLite 存元数据 + HNSW 做向量索引,所以你的 chroma_db 目录可以直接复制走当备份。

Qdrant:要服务化才上

Rust 写的,Apache-2.0,2026 年 9 月的稳定版是 1.19.x。它比另外两个重,但重的地方都有回报。

双端口坑,几乎人人踩一次。 REST 在 6333,gRPC 在 6334。网页控制台走 REST,Python 客户端默认走 gRPC。你只映射 6333,控制台一切正常,Python 一连接就失败,报错还指向别处。

docker run -d --name qdrant --restart unless-stopped \  -p 127.0.0.1:6333:6333 -p 127.0.0.1:6334:6334 \  -v $(pwd)/qdrant_storage:/qdrant/storage \  -e QDRANT__SERVICE__API_KEY=$(openssl rand -hex 32) \  qdrant/qdrant:v1.19.1

注意那个 127.0.0.1:。直接写 -p 6333:6333 会绑到所有网卡,局域网里任何人都能读写你的整个索引。

API Key 不是可选项。 不设 QDRANT__SERVICE__API_KEY,任何能访问 6333 的进程都拥有完整读写权限,连删除都不需要认证。

量化是它最值钱的功能。 2026 年 Qdrant 有四种:标量(float32→int8,省 4 倍)、二元(省 32 倍)、乘积、以及 1.18 引入的 TurboQuant(1.19 里做成 4-bit 的 Turbo4 存储格式,不再保留全精度副本)。1000 万条 768 维向量原始要 30 GB,标量量化后 7.5 GB 左右,笔记本也扛得住。

不过量化会掉召回。上之前拿二三十条真实问题跑一遍,对比开关前后的 recall@10。有些嵌入模型量化后质量掉得比你以为的多。

不想开 Docker 也能用:QdrantClient(path="./qdrant_db") 是本地模式,进程内跑,功能不打折。

LanceDB:最像"一个文件夹"的那个

我最后装的是它。理由很简单:没有服务,没有端口,没有守护进程。

pip install lancedb
import lancedbdb = lancedb.connect("./lancedb")tbl = db.create_table("notes", data=rows, mode="overwrite")   # rows 里带 vector 和 metadatatbl.create_index(metric="cosine", index_type="IVF_PQ",                 num_partitions=256, num_sub_vectors=96)hits = (tbl.search(query_vec)           .where("tags = 'RAG'")      # 过滤和向量检索同一次调用           .distance_type("cosine")           .limit(8).to_list())

它的三个特点:

磁盘原生。 数据落在 Lance 列式文件里(Parquet 兼容),不是"内存里建好再落盘"。库比内存大也没事,按需读。

元数据过滤跟向量检索是同一次调用,因为过滤字段和向量在同一个文件里。Chroma 要分两步,Qdrant 要在 payload 上建索引。

公开基准很好看:LanceDB 0.38(2026 年 9 月,4 核 CPU 无 GPU)在 118 万条 100 维向量上,IVF_PQ 索引构建不到半分钟,整份索引 488 MiB,p95 查询 6 毫秒。这是官方生态的基准数字,不是我跑的,但它说明"嵌入式"不等于玩具。

两个坑:

向量维度写死在 schema 里,改不了。 你用 384 维的 all-minilm 建了表,哪天想换成 768 维的 nomic,只能新建一张表重来。建表前先想清楚模型。

写多读少的场景别用它。 Lance 格式是为读优化的。你要是每分钟都在批量插入,去找 Qdrant。

另外,老机器(没有 AVX2 的 x86 CPU)装 lancedb 会直接 Illegal instruction,改装 lancedb-compat,两个包共用命名空间,装之前先卸另一个。

磁盘账:48.8 万块要吃多少

回到开头那个库。48.8 万块,不同维度下的原始向量体积:

维度
原始向量
加索引后(约 1.3~1.5 倍)
代表模型
384
715 MB
~1.0 GB
all-minilm
768
1.5 GB
~2.1 GB
nomic-embed-text v1.5
1024
2.0 GB
~2.8 GB
bge-m3 / qwen3-embedding

公式就一行:块数 × 维度 × 4 字节。

对比一下:一个 2,000 篇、平均 1,500 字的库,才 4,400 块,768 维索引 13.5 MB,几秒钟建完。

所以我那个三小时二十八分,不是向量数据库的锅,是我的库太大——其中 830 篇超过 200 KB 的法规标准原文就占了 368 MB,一半的体量压在 5% 的文件上。

先算这个账,再决定要不要装。

增量索引:三件事做对,第二次只要几十秒

全量跑一次是逃不掉的,但第二次不该再跑三小时。增量索引做对三件事就行:

一、用 mtime + 内容哈希双判。 只看 mtime 会被同步工具骗(文件时间变了内容没变),只看哈希就要读全库。先比 mtime,变了再读文件算哈希。

二、删除要显式处理。 笔记删了、或者从 3000 字改到 300 字,旧的块不会自己消失。这些孤儿块会污染检索结果——你搜到一段早就不存在的内容。按 path 字段先把旧的查出来删掉,再插新的。

三、换模型必须全量重建。 这是唯一没法增量的情况。不同模型的向量空间不兼容,混在一起等于拿中文去比英文。重建前把旧目录整个复制一份留着。

import hashlib, os, sqlite3defchanged(path, state):    st = os.stat(path)if state.get(path, (0, ""))[0] == st.st_mtime:returnNone    h = hashlib.sha256(open(path, "rb").read()).hexdigest()[:16]if state.get(path, ("", ""))[1] == h:returnNonereturn h# 伪代码骨架:# 1. 扫全库,用 changed() 过滤出真正变了的笔记# 2. 对每条:DELETE FROM chunks WHERE path = ?   ← 先清旧块# 3. 重新切块 + 嵌入 + 插入# 4. 扫一遍 state 里已不存在于磁盘的 path,删掉它们的块

第 2 步那个 DELETE 是最容易漏的。我第一版脚本就漏了,改完一篇笔记之后,检索结果里还留着它被删掉的那段话,找了半天才想明白。

三条红线

一、向量库的服务端口绝不绑 0.0.0.0。 Qdrant 的 6333、Chroma 的 8000,映射到宿主机时一律写成 127.0.0.1:端口:端口。不带 API Key 的 Qdrant 和裸奔的 Chroma 在公网上活不过一天——这不是理论风险,同类服务(Ollama 的 11434)已经被普查到十几万个公网裸奔实例。真要跨机器访问,走 SSH 隧道或者 Tailscale 这类组网,别开端口映射。

二、动写删操作之前先备份索引。 换嵌入模型 = 全量重建,这是不可逆的几小时。重建前 cp -r chroma_db chroma_db.bak,或者用 Qdrant 的快照。同理,让 Agent 或脚本拿到索引的写权限之前,先确认它有备份,并且只在测试 collection 上试。

三、密钥别写进库。 你用云端嵌入模型就有 API Key,别写在 .env 里还放在 vault 内——那份文件会跟着同步到每台设备、每个网盘。Obsidian 1.11.4 起的 SecretStorage 走系统钥匙串,Copilot 3.x 已经接入,但它只覆盖苹果生态:macOS 走 Keychain,iOS 走钥匙串,Android 对应的是 Keystore,Windows 上则要用凭据管理器。别指望跨平台统一。

速查表

场景
选哪个
5000 篇以内,只在 Obsidian 里搜
插件内索引,别装
想在 Python 脚本里复用索引
LanceDB 或 Chroma 进程内
索引比内存大
LanceDB(磁盘原生)
要按标签/年份/作者过滤
Qdrant 或 LanceDB
要省内存、上千万向量
Qdrant + 标量量化
多机/多人共读一份
Qdrant 或 Chroma 服务模式
老 CPU、不想折腾 Docker
LanceDB(注意 AVX2)
只是想试试 RAG 是什么
插件内索引,十分钟搞定

系列进度:方向④ 本地大模型 RAG · 第 3 篇(总第 25 篇)。下一篇讲语义检索真正跑起来是什么样——Copilot 接 Ollama 做 Vault QA,以及我实测时的一个翻车现场。

问你一个问题:你算过自己库的全量索引时间吗?把篇数和总字数甩在评论区,我帮你估一个数——超过两小时的,值得单独聊聊切分策略。

随机文章