共计 2129 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要向量数据库?
传统的关系型数据库在处理高维向量数据时存在明显的局限性。比如,当我们需要计算两个向量的相似度(如余弦相似度)时,MySQL 或 PostgreSQL 这类数据库需要全表扫描才能完成,效率极低。随着数据量增长,这个问题会更加严重。

- 相似度计算效率低 :传统数据库没有针对向量搜索优化,无法利用近似最近邻(ANN) 算法加速
- 横向扩展困难:单机架构难以应对海量向量数据的存储和查询需求
- 缺乏专业索引:无法高效支持 IVF、HNSW 等专门为向量设计的索引结构
主流向量数据库技术对比
目前市场上主要有三种解决方案:
- Milvus:开源分布式向量数据库,支持多种索引算法和标量过滤
- Pinecone:全托管云服务,简单易用但灵活性较低
- FAISS:Facebook 开发的库,需要自行处理持久化和分布式
架构差异对比
| 特性 | Milvus | Pinecone | FAISS |
|---|---|---|---|
| 分布式 | ✅ 支持 | ❌ 单租户 | ❌ 需自行实现 |
| 算法支持 | IVF/HNSW/ANNOY | HNSW | IVF/HNSW |
| 云原生 | 需要部署 | ✅ 全托管 | ❌ 纯库 |
| 标量过滤 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
实战:用 Python 操作 Milvus
环境准备
首先安装必要的 Python 包:
pip install pymilvus==2.0.0
基础工作流示例
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
# 连接配置
HOST = 'localhost'
PORT = '19530'
connections.connect(host=HOST, port=PORT)
# 定义集合结构
fields = [FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=128)
]
schema = CollectionSchema(fields, description="商品向量库")
collection_name = "products"
collection = Collection(collection_name, schema)
# 插入数据
data = [[i for i in range(100)], # ID 列表
[[random.random() for _ in range(128)] for _ in range(100)] # 向量列表
]
collection.insert(data)
# 创建索引
index_params = {
"metric_type": "L2",
"index_type": "IVF_FLAT",
"params": {"nlist": 1024}
}
collection.create_index("embedding", index_params)
# 搜索示例
search_params = {"metric_type": "L2", "params": {"nprobe": 10}}
results = collection.search(data=[[random.random() for _ in range(128)]],
anns_field="embedding",
param=search_params,
limit=5
)
性能优化实战
索引参数调优
IVF 索引有两个关键参数:
- nlist:聚类中心数量
- 值越大精度越高,但构建时间越长
-
建议设置为 sqrt(N)到 N /10,其中 N 是向量总数
-
nprobe:搜索时检查的聚类数量
- 值越大召回率越高,但查询延迟增加
- 生产环境通常设为 5 -20
基准测试建议
# 测试不同 nprobe 对 QPS 的影响
for nprobe in [5, 10, 20, 50]:
search_params["params"]["nprobe"] = nprobe
start = time.time()
# 执行 100 次查询
print(f"nprobe={nprobe}, QPS={100/(time.time()-start)}")
常见问题解决方案
内存泄漏预防
-
总是释放查询结果:
results = collection.search(...) # 使用后立即释放 del results -
批量插入时分片处理(建议每批 1 万 - 5 万条):
batch_size = 20000 for i in range(0, len(vectors), batch_size): collection.insert(vectors[i:i+batch_size])
进阶思考:混合查询实现
实际业务中经常需要同时使用向量搜索和标量过滤,比如:
“ 找出与目标图片最相似的 10 个商品,且价格低于 100 元 ”
Milvus 通过 expr 参数支持这种场景:
search_params = {
"expr": "price < 100",
"params": {"nprobe": 10}
}
总结与展望
通过本文的实践,我们完成了从零开始使用 Milvus 搭建向量搜索服务的全过程。向量数据库在推荐系统、图像检索、自然语言处理等领域都有广泛应用前景。未来可以考虑:
- 结合缓存层优化热点查询
- 探索多模态向量联合搜索
- 实现动态更新下的索引平衡
希望这篇指南能帮助你快速上手 AI 向量数据库的开发工作。
正文完
