索引管理 #
一、索引概述 #
索引是提高查询性能的重要手段,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
});
十三、总结 #
索引管理要点:
- Hash索引:等值查询
- SkipList索引:范围查询和排序
- Fulltext索引:文本搜索
- Geo索引:地理位置查询
- TTL索引:自动过期删除
下一步,让我们学习高级特性!
最后更新:2026-03-27