索引与性能 #
本章详细介绍 Weaviate 的索引机制和性能优化方法。
索引架构 #
text
Weaviate 索引架构:
┌─────────────────────────────────────────────────────────────┐
│ 索引类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 向量索引 (Vector Index) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ HNSW │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Layer 2 │ │ Layer 1 │ │ Layer 0 │ │ │
│ │ │ (稀疏) │ │ (中等) │ │ (密集) │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 倒排索引 (Inverted Index) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 属性 → 对象 ID 映射 │ │
│ │ category: 技术 → [id1, id2, ...] │ │
│ │ views: 1000 → [id3, id4, ...] │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 地理索引 (Geo Index) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 基于 GeoHash 的空间索引 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
HNSW 索引 #
HNSW 原理 #
text
HNSW (Hierarchical Navigable Small World):
特点:
├── 多层图结构
├── 快速近似最近邻搜索
├── O(log n) 查询复杂度
└── 支持动态更新
搜索流程:
1. 从顶层开始
2. 在每层找到最近邻
3. 逐层向下细化
4. 底层返回结果
Layer 2 (稀疏) ○─────────────────○
│ │
Layer 1 (中等) ○───○─────────○───○
│ │ │ │
Layer 0 (密集) ○─○─○─○─○─○─○─○─○─○─○
基本配置 #
python
import weaviate.classes as wvc
articles = client.collections.create(
name="Article",
vectorizer_config=wvc.config.Configure.Vectorizer.none(),
vector_index_config=wvc.config.Configure.VectorIndex.hnsw(
distance_metric=wvc.config.VectorDistance.COSINE,
ef_construction=128,
max_connections=64
),
properties=[
wvc.config.Property(name="title", data_type=wvc.config.DataType.TEXT)
]
)
参数详解 #
text
HNSW 参数说明:
ef_construction:
├── 构建索引时的搜索范围
├── 值越大,索引质量越高
├── 构建时间越长
├── 推荐值: 128-512
└── 默认值: 128
max_connections:
├── 每个节点的最大连接数
├── 值越大,召回率越高
├── 内存占用越大
├── 推荐值: 16-64
└── 默认值: 32
ef:
├── 查询时的搜索范围
├── 值越大,召回率越高
├── 查询时间越长
├── 推荐值: 64-256
├── 默认值: -1 (动态)
└── 可以在查询时覆盖
高级配置 #
python
articles = client.collections.create(
name="Article",
vectorizer_config=wvc.config.Configure.Vectorizer.none(),
vector_index_config=wvc.config.Configure.VectorIndex.hnsw(
distance_metric=wvc.config.VectorDistance.COSINE,
ef_construction=256,
max_connections=64,
ef=128,
dynamic_ef_min=50,
dynamic_ef_max=500,
dynamic_ef_factor=8,
skip=False,
cleanup_interval_seconds=300
),
properties=[
wvc.config.Property(name="title", data_type=wvc.config.DataType.TEXT)
]
)
动态 EF #
text
动态 EF 计算:
ef = min(
dynamic_ef_max,
max(dynamic_ef_min, limit * dynamic_ef_factor)
)
示例:
├── limit = 10
├── dynamic_ef_factor = 8
├── dynamic_ef_min = 50
├── dynamic_ef_max = 500
└── ef = min(500, max(50, 10 * 8)) = 80
向量量化 #
量化可以显著减少内存占用,适合大规模向量数据。
PQ 量化 (Product Quantization) #
python
articles = client.collections.create(
name="Article",
vectorizer_config=wvc.config.Configure.Vectorizer.text2vec_openai(),
vector_index_config=wvc.config.Configure.VectorIndex.hnsw(
distance_metric=wvc.config.VectorDistance.COSINE,
quantizer=wvc.config.Configure.VectorIndex.Quantizer.pq(
segments=64,
centroids=256,
training_limit=100000,
encoder=wvc.config.Configure.VectorIndex.Quantizer.PQ.Encoder(
type_=wvc.config.Configure.VectorIndex.Quantizer.PQ.Encoder.Type.KMEANS,
distribution=wvc.config.Configure.VectorIndex.Quantizer.PQ.Encoder.Distribution.LOG_NORMAL
)
)
),
properties=[
wvc.config.Property(name="title", data_type=wvc.config.DataType.TEXT),
wvc.config.Property(name="content", data_type=wvc.config.DataType.TEXT)
]
)
PQ 参数说明 #
text
PQ 量化参数:
segments:
├── 向量分段数量
├── 影响压缩率和精度
├── 推荐值: 向量维度 / 8
└── 示例: 1536 维向量 → 192 segments
centroids:
├── 每段的聚类中心数
├── 影响精度和内存
├── 必须是 2 的幂
└── 推荐值: 256 或 512
training_limit:
├── 训练样本数量
├── 用于学习聚类中心
└── 推荐值: 10000-100000
BQ 量化 (Binary Quantization) #
python
articles = client.collections.create(
name="Article",
vectorizer_config=wvc.config.Configure.Vectorizer.text2vec_openai(),
vector_index_config=wvc.config.Configure.VectorIndex.hnsw(
distance_metric=wvc.config.VectorDistance.COSINE,
quantizer=wvc.config.Configure.VectorIndex.Quantizer.bq(
cache=True
)
),
properties=[
wvc.config.Property(name="title", data_type=wvc.config.DataType.TEXT),
wvc.config.Property(name="content", data_type=wvc.config.DataType.TEXT)
]
)
量化对比 #
text
量化方式对比:
┌──────────────┬──────────────┬──────────────┬───────────────┐
│ 方式 │ 内存占用 │ 召回率 │ 速度 │
├──────────────┼──────────────┼──────────────┼───────────────┤
│ 无量化 │ 100% │ 100% │ 基准 │
│ PQ 量化 │ ~10% │ ~95% │ 更快 │
│ BQ 量化 │ ~3% │ ~90% │ 最快 │
└──────────────┴──────────────┴──────────────┴───────────────┘
选择建议:
├── 内存充足: 无量化
├── 大规模数据: PQ 量化
└── 极致压缩: BQ 量化
倒排索引 #
配置倒排索引 #
python
articles = client.collections.create(
name="Article",
properties=[
wvc.config.Property(
name="title",
data_type=wvc.config.DataType.TEXT,
index_filterable=True,
index_searchable=True,
tokenization=wvc.config.Tokenization.WORD
),
wvc.config.Property(
name="category",
data_type=wvc.config.DataType.TEXT,
index_filterable=True
),
wvc.config.Property(
name="views",
data_type=wvc.config.DataType.INT,
index_filterable=True,
index_range_filters=True
),
wvc.config.Property(
name="tags",
data_type=wvc.config.DataType.TEXT_ARRAY,
index_filterable=True
)
]
)
索引配置说明 #
text
倒排索引配置:
index_filterable:
├── 启用过滤索引
├── 支持 =, !=, <, > 等操作
└── 推荐为常用过滤字段启用
index_searchable:
├── 启用全文搜索索引
├── 支持 BM25 搜索
└── 仅适用于文本字段
index_range_filters:
├── 启用范围过滤优化
├── 加速范围查询
└── 适用于数值字段
tokenization:
├── word: 按词分词
├── lowercase: 小写分词
├── whitespace: 按空格分词
├── field: 字段级分词
└── trigram: 三元组分词
性能优化策略 #
内存优化 #
python
articles = client.collections.create(
name="Article",
vectorizer_config=wvc.config.Configure.Vectorizer.text2vec_openai(
model="text-embedding-3-small",
dimensions=512
),
vector_index_config=wvc.config.Configure.VectorIndex.hnsw(
distance_metric=wvc.config.VectorDistance.COSINE,
quantizer=wvc.config.Configure.VectorIndex.Quantizer.bq(cache=True)
),
properties=[
wvc.config.Property(
name="title",
data_type=wvc.config.DataType.TEXT,
index_filterable=True
),
wvc.config.Property(
name="content",
data_type=wvc.config.DataType.TEXT,
index_filterable=False,
index_searchable=False
)
]
)
查询优化 #
python
articles = client.collections.get("Article")
response = articles.query.near_text(
query="向量数据库",
filters=Filter.by_property("category").equal("技术"),
limit=10,
autocut=1
)
批量操作优化 #
python
articles = client.collections.get("Article")
with articles.batch.fixed_size(batch_size=500) as batch:
for i in range(10000):
batch.add_object(
properties={
"title": f"文章 {i}",
"content": f"内容 {i}"
}
)
if batch.num_objects % 1000 == 0:
print(f"Processed {batch.num_objects} objects")
性能基准 #
内存估算 #
text
内存估算公式:
基础内存 = 向量数 × 向量维度 × 4 字节
HNSW 索引开销 ≈ 30-50%
示例:
├── 100 万向量
├── 1536 维度
├── 基础内存: 100万 × 1536 × 4 = 6 GB
├── HNSW 开销: ~2 GB
└── 总内存: ~8 GB
量化后:
├── PQ: ~0.8 GB
├── BQ: ~0.25 GB
查询性能 #
text
典型查询性能:
数据规模: 100 万向量
维度: 1536
召回率: 95%
无量化:
├── P50 延迟: ~5ms
├── P99 延迟: ~15ms
└── QPS: ~2000
PQ 量化:
├── P50 延迟: ~3ms
├── P99 延迟: ~10ms
└── QPS: ~3000
BQ 量化:
├── P50 延迟: ~2ms
├── P99 延迟: ~8ms
└── QPS: ~4000
性能调优指南 #
参数调优 #
text
高召回率场景:
├── ef_construction: 256-512
├── max_connections: 48-64
├── ef: 128-256
└── 不使用量化
高吞吐量场景:
├── ef_construction: 64-128
├── max_connections: 16-32
├── ef: 32-64
└── 使用 BQ 量化
平衡场景:
├── ef_construction: 128-256
├── max_connections: 32-48
├── ef: 64-128
└── 使用 PQ 量化
硬件建议 #
text
硬件配置建议:
CPU:
├── 向量计算密集
├── 推荐多核处理器
└── 建议: 8+ 核心
内存:
├── 向量数据内存驻留
├── 根据数据规模配置
└── 建议: 32GB+
存储:
├── SSD 推荐
├── 影响 I/O 性能
└── 建议: NVMe SSD
网络:
├── 分布式部署需要
├── 低延迟网络
└── 建议: 10Gbps+
监控指标 #
关键指标 #
text
关键监控指标:
查询性能:
├── 查询延迟 (P50, P99)
├── QPS (每秒查询数)
└── 错误率
索引性能:
├── 导入速度
├── 索引构建时间
└── 索引大小
资源使用:
├── 内存使用率
├── CPU 使用率
├── 磁盘 I/O
└── 网络带宽
小结 #
本章介绍了 Weaviate 的索引和性能优化:
- HNSW 索引原理和配置
- 向量量化(PQ、BQ)
- 倒排索引配置
- 性能优化策略
- 性能基准和调优指南
下一步 #
继续学习 分布式部署,了解如何构建高可用集群!
最后更新:2026-04-04