索引与性能 #

本章详细介绍 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