索引管理 #

一、索引概述 #

索引是提高查询性能的重要手段,ArangoDB支持多种索引类型。

1.1 索引类型 #

类型 说明 适用场景
primary 主键索引 自动创建
hash 哈希索引 等值查询
skiplist 跳表索引 范围查询、排序
persistent 持久化索引 等值和范围查询
fulltext 全文索引 文本搜索
geo 地理索引 地理位置查询
ttl TTL索引 自动过期
inverted 倒排索引 ArangoSearch

1.2 索引选择原则 #

text
索引选择:
├── 等值查询 → Hash索引
├── 范围查询 → SkipList/Persistent索引
├── 排序查询 → SkipList/Persistent索引
├── 文本搜索 → Fulltext/Inverted索引
├── 地理查询 → Geo索引
└── 自动过期 → TTL索引

二、主键索引 #

2.1 自动创建 #

每个集合自动创建主键索引:

javascript
db.users.getIndexes();

输出:

json
[
    {
        "id": "0",
        "type": "primary",
        "unique": true,
        "fields": ["_key"]
    }
]

2.2 主键查询 #

aql
FOR user IN users
    FILTER user._key == "user_001"
    RETURN user

三、Hash索引 #

3.1 创建Hash索引 #

javascript
db.users.ensureHashIndex(["email"]);

3.2 唯一Hash索引 #

javascript
db.users.ensureHashIndex(["email"], { unique: true });

3.3 稀疏索引 #

javascript
db.users.ensureHashIndex(["phone"], { sparse: true });

3.4 复合Hash索引 #

javascript
db.users.ensureHashIndex(["city", "status"]);

3.5 使用场景 #

aql
FOR user IN users
    FILTER user.email == "zhangsan@example.com"
    RETURN user

3.6 Hash索引特点 #

特点 说明
等值查询 高效
范围查询 不支持
排序 不支持
唯一性 支持
稀疏 支持

四、SkipList索引 #

4.1 创建SkipList索引 #

javascript
db.users.ensureSkipList(["age"]);

4.2 复合SkipList索引 #

javascript
db.users.ensureSkipList(["city", "age"]);

4.3 唯一SkipList索引 #

javascript
db.users.ensureSkipList(["username"], { unique: true });

4.4 使用场景 #

范围查询:

aql
FOR user IN users
    FILTER user.age >= 20 AND user.age <= 30
    RETURN user

排序查询:

aql
FOR user IN users
    SORT user.age DESC
    RETURN user

4.5 SkipList索引特点 #

特点 说明
等值查询 高效
范围查询 高效
排序 高效
唯一性 支持
稀疏 支持

五、Persistent索引 #

5.1 创建Persistent索引 #

javascript
db.users.ensureIndex({
    type: "persistent",
    fields: ["name", "age"]
});

5.2 唯一Persistent索引 #

javascript
db.users.ensureIndex({
    type: "persistent",
    fields: ["email"],
    unique: true
});

5.3 稀疏Persistent索引 #

javascript
db.users.ensureIndex({
    type: "persistent",
    fields: ["middleName"],
    sparse: true
});

5.4 Persistent vs SkipList #

特性 Persistent SkipList
存储 磁盘持久化 内存
恢复 自动恢复 需重建
性能 略低 略高

六、Fulltext索引 #

6.1 创建Fulltext索引 #

javascript
db.articles.ensureFulltextIndex(["title"]);

6.2 多字段Fulltext索引 #

javascript
db.articles.ensureFulltextIndex(["title", "content"]);

6.3 使用全文搜索 #

aql
FOR doc IN FULLTEXT(articles, "title", "数据库")
    RETURN doc

6.4 复杂搜索 #

aql
FOR doc IN FULLTEXT(articles, "title", "数据库|ArangoDB")
    RETURN doc

6.5 带权重的搜索 #

aql
FOR doc IN FULLTEXT(articles, "title", "数据库")
    RETURN {
        title: doc.title,
        score: BM25(doc)
    }

七、Geo索引 #

7.1 创建Geo索引 #

javascript
db.locations.ensureGeoIndex(["coordinates"]);

7.2 地理位置文档结构 #

json
{
    "name": "北京",
    "coordinates": [116.4074, 39.9042]
}

7.3 附近查询 #

aql
FOR loc IN NEAR(locations, 116.4074, 39.9042, 10)
    RETURN {
        name: loc.name,
        distance: loc.distance
    }

7.4 范围查询 #

aql
FOR loc IN WITHIN(locations, 116.4074, 39.9042, 10000)
    RETURN {
        name: loc.name,
        distance: loc.distance
    }

7.5 多边形查询 #

aql
LET polygon = [
    [116.0, 39.0],
    [117.0, 39.0],
    [117.0, 40.0],
    [116.0, 40.0],
    [116.0, 39.0]
]
FOR loc IN WITHIN_POLYGON(locations, polygon)
    RETURN loc

八、TTL索引 #

8.1 创建TTL索引 #

javascript
db.sessions.ensureIndex({
    type: "ttl",
    fields: ["expiresAt"],
    expireAfter: 0
});

8.2 文档结构 #

json
{
    "_key": "session_001",
    "userId": "user_001",
    "expiresAt": "2024-01-15T10:30:00Z"
}

8.3 自动删除 #

TTL索引会自动删除过期文档:

javascript
db.sessions.ensureIndex({
    type: "ttl",
    fields: ["createdAt"],
    expireAfter: 3600
});

九、Inverted索引 #

9.1 创建Inverted索引 #

javascript
db.articles.ensureIndex({
    type: "inverted",
    fields: ["title", "content"]
});

9.2 带分析器的索引 #

javascript
db.articles.ensureIndex({
    type: "inverted",
    fields: [
        { name: "title", analyzer: "text_zh" },
        { name: "content", analyzer: "text_zh" }
    ]
});

9.3 使用ArangoSearch #

aql
FOR doc IN articles
    SEARCH ANALYZER(doc.title IN TOKENS("数据库", "text_zh"), "text_zh")
    RETURN doc

十、索引管理 #

10.1 查看索引 #

javascript
db.users.getIndexes();

10.2 查看特定索引 #

javascript
db.users.index("idx_123");

10.3 删除索引 #

javascript
db.users.dropIndex("idx_123");

10.4 删除所有索引 #

javascript
db.users.dropIndexes();

10.5 索引统计 #

javascript
db.users.indexes(true);

十一、索引优化 #

11.1 查询分析 #

javascript
db._explain(`
    FOR user IN users
        FILTER user.email == "test@example.com"
        RETURN user
`);

11.2 索引使用情况 #

javascript
db._query(`
    FOR user IN users
        FILTER user.email == "test@example.com"
        RETURN user
`).getExtra().stats;

11.3 索引选择建议 #

text
建议:
├── 为常用查询条件创建索引
├── 避免过多索引
├── 复合索引注意字段顺序
├── 定期分析索引使用情况
└── 删除未使用的索引

11.4 复合索引设计 #

javascript
db.orders.ensureSkipList(["userId", "createdAt"]);

查询优化:

aql
FOR order IN orders
    FILTER order.userId == "user_001"
    SORT order.createdAt DESC
    RETURN order

十二、实战示例 #

12.1 用户表索引 #

javascript
db.users.ensureHashIndex(["email"], { unique: true });
db.users.ensureHashIndex(["username"], { unique: true });
db.users.ensureSkipList(["createdAt"]);
db.users.ensureHashIndex(["status"]);

12.2 订单表索引 #

javascript
db.orders.ensureHashIndex(["userId"]);
db.orders.ensureSkipList(["createdAt"]);
db.orders.ensureSkipList(["status", "createdAt"]);
db.orders.ensureHashIndex(["orderNo"], { unique: true });

12.3 文章表索引 #

javascript
db.articles.ensureSkipList(["publishedAt"]);
db.articles.ensureHashIndex(["authorId"]);
db.articles.ensureHashIndex(["category"]);
db.articles.ensureFulltextIndex(["title", "content"]);

12.4 会话表索引 #

javascript
db.sessions.ensureHashIndex(["token"], { unique: true });
db.sessions.ensureIndex({
    type: "ttl",
    fields: ["expiresAt"],
    expireAfter: 0
});

十三、总结 #

索引管理要点:

  1. Hash索引:等值查询
  2. SkipList索引:范围查询和排序
  3. Fulltext索引:文本搜索
  4. Geo索引:地理位置查询
  5. TTL索引:自动过期删除

下一步,让我们学习高级特性!

最后更新:2026-03-27