向量数据库速查表
快速查阅向量数据库的核心概念、操作和最佳实践。
核心概念速查
向量数据库对比
| 数据库 | 类型 | 最佳场景 | 数据规模 |
|---|---|---|---|
| Pinecone | 全托管云服务 | 快速上线、无运维 | 任意规模 |
| Milvus | 开源/云原生 | 大规模生产 | 十亿级+ |
| Weaviate | 开源/托管 | 复杂查询、GraphQL | 千万级 |
| Qdrant | 开源/托管 | 高性能、资源受限 | 千万级 |
| Chroma | 开源 | 快速原型、本地开发 | 百万级 |
| pgvector | PG 扩展 | 已有 PG 基础设施 | 千万级 |
相似度度量
| 度量 | 符号 | 范围 | 适用场景 |
|---|---|---|---|
| 余弦相似度 | <=> | [-1, 1] | 文本语义搜索 |
| 欧几里得距离 | <-> | [0, +∞) | 几何/物理数据 |
| 点积 | <#> | 无限制 | 已归一化向量 |
ANN 索引算法
| 算法 | 时间复杂度 | 特点 | 适用场景 |
|---|---|---|---|
| HNSW | O(log n) | 搜索快、内存高 | 通用首选 |
| IVF | O(√n) | 平衡速度/内存 | 大规模数据 |
| PQ | O(1) | 压缩存储 | 内存受限 |
| Flat | O(n) | 100%精确 | 小规模数据 |
嵌入模型速查
常用模型
| 模型 | 维度 | 语言 | 特点 |
|---|---|---|---|
| text-embedding-3-small | 1536 | 多语言 | OpenAI,性价比高 |
| text-embedding-3-large | 3072 | 多语言 | OpenAI,高精度 |
| all-MiniLM-L6-v2 | 384 | 英文 | 轻量快速 |
| paraphrase-multilingual | 384 | 多语言 | 支持中文 |
| BAAI/bge-large-zh | 1024 | 中文 | 中文最优 |
| M3E-base | 768 | 中文 | 开源中文 |
模型选择指南
英文通用 → text-embedding-3-small
英文高精度 → text-embedding-3-large
中文场景 → BAAI/bge-large-zh
资源受限 → all-MiniLM-L6-v2
多语言 → paraphrase-multilingual
代码速查
Pinecone
from pinecone import Pinecone, ServerlessSpec
# 连接
pc = Pinecone(api_key="your-api-key")
# 创建索引
pc.create_index(
name="my-index",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(cloud="aws", region="us-east-1")
)
# 连接索引
index = pc.Index("my-index")
# 插入
index.upsert(vectors=[
{"id": "vec1", "values": [0.1, 0.2, ...], "metadata": {"key": "value"}}
])
# 查询
results = index.query(
vector=[0.1, 0.2, ...],
top_k=10,
filter={"category": {"$eq": "tech"}}
)
Milvus
from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection
# 连接
connections.connect("default", host="localhost", port="19530")
# 创建集合
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=512),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1536)
]
schema = CollectionSchema(fields, "my_collection")
collection = Collection("my_collection", schema)
# 创建索引
index_params = {
"metric_type": "COSINE",
"index_type": "HNSW",
"params": {"M": 16, "efConstruction": 200}
}
collection.create_index("embedding", index_params)
# 插入
collection.insert([["text1", "text2"], [vec1, vec2]])
# 加载并搜索
collection.load()
results = collection.search(
data=[query_vector],
anns_field="embedding",
param={"metric_type": "COSINE", "params": {"ef": 64}},
limit=10
)
Chroma
import chromadb
# 客户端
client = chromadb.PersistentClient(path="./chroma_db")
# 创建集合
collection = client.create_collection(name="my_collection")
# 添加
collection.add(
documents=["doc1", "doc2"],
metadatas=[{"category": "tech"}, {"category": "life"}],
ids=["id1", "id2"]
)
# 查询
results = collection.query(
query_texts=["query"],
n_results=10,
where={"category": "tech"}
)
Qdrant
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
# 连接
client = QdrantClient(host="localhost", port=6333)
# 创建集合
client.create_collection(
collection_name="my_collection",
vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
)
# 插入
client.upsert(
collection_name="my_collection",
points=[
PointStruct(id=1, vector=[0.1, 0.2, ...], payload={"text": "doc"})
]
)
# 搜索
results = client.search(
collection_name="my_collection",
query_vector=[0.1, 0.2, ...],
query_filter=Filter(must=[FieldCondition(key="category", match=MatchValue(value="tech"))]),
limit=10
)
pgvector (SQL)
-- 创建扩展
CREATE EXTENSION vector;
-- 创建表
CREATE TABLE items (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536)
);
-- 创建索引
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);
-- 插入
INSERT INTO items (content, embedding)
VALUES ('text', '[0.1, 0.2, ...]');
-- 查询
SELECT id, content, embedding <=> '[0.1, 0.2, ...]' AS distance
FROM items
ORDER BY embedding <=> '[0.1, 0.2, ...]'
LIMIT 10;
RAG 流程速查
1. 文档加载 → 2. 文本切分 → 3. 生成嵌入 → 4. 存入向量库
↓
5. 生成回答 ← 6. 调用 LLM ← 7. 构建上下文 ← 8. 检索相关文档
文档切分策略
| 策略 | 适用场景 | 代码示例 |
|---|---|---|
| 按段落 | 通用场景 | text.split('\n\n') |
| 按句子 | 短文本 | text.split('。') |
| 固定长度 | 长文档 | text[i:i+chunk_size] |
| 重叠切分 | 保持上下文 | text[i:i+chunk_size] + overlap |
提示词模板
RAG_PROMPT = """基于以下文档回答问题。如果文档中没有相关信息,请说明。
文档:
{context}
问题:{question}
回答:"""
性能优化速查
批量大小建议
| 操作 | 推荐批量大小 | 说明 |
|---|---|---|
| 插入 | 100-1000 | 平衡速度和内存 |
| 查询 | 10-100 | 根据延迟要求调整 |
| 嵌入生成 | 100-500 | 取决于 API 限制 |
索引参数
HNSW 索引:
{
"M": 16, # 2-100,越大精度越高
"efConstruction": 200, # 100-500,越大构建越慢
"ef": 64 # 搜索时,> top_k
}
IVF 索引:
{
"nlist": 128, # 聚类中心数 ≈ 4×√数据量
"nprobe": 10 # 搜索时,10-100
}
数据规模建议
| 数据量 | 推荐索引 | 部署方式 |
|---|---|---|
| < 10万 | Flat / 无索引 | 单机 |
| 10万-1000万 | HNSW / IVF | 单机 |
| 1000万-1亿 | HNSW | 分布式 |
| > 1亿 | IVF_PQ | 分布式集群 |
故障排查速查
常见问题
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 查询结果为空 | 未加载集合 | collection.load() |
| 搜索结果不准确 | 索引参数不当 | 调整 M/efConstruction |
| 内存不足 | 数据量过大 | 使用量化索引 |
| 查询速度慢 | 未创建索引 | 创建 HNSW/IVF 索引 |
| 维度不匹配 | 模型维度错误 | 检查向量维度 |
调试命令
# 检查集合信息
collection.get_stats()
# 查看索引进度
collection.index().progress
# 验证数据
collection.query(expr="id >= 0", output_fields=["*"])
选型决策树
是否需要事务/Join?
├── 是 → pgvector
└── 否 → 继续
是否有运维团队?
├── 否 → Pinecone
└── 是 → 继续
数据规模?
├── < 100万 → Chroma
├── 100万-1000万 → Qdrant / Weaviate
└── > 1000万 → Milvus
资源链接
官方文档
- Pinecone: https://docs.pinecone.io/
- Milvus: https://milvus.io/docs
- Weaviate: https://weaviate.io/developers
- Qdrant: https://qdrant.tech/documentation/
- Chroma: https://docs.trychroma.com/
- pgvector: https://github.com/pgvector/pgvector
嵌入模型
- OpenAI: https://platform.openai.com/docs/guides/embeddings
- Sentence Transformers: https://www.sbert.net/
- Hugging Face: https://huggingface.co/models