性能优化 #
一、性能优化概述 #
性能优化是提高数据库响应速度和处理能力的关键。
1.1 优化方向 #
| 方向 | 说明 |
|---|---|
| 查询优化 | 优化AQL查询语句 |
| 索引优化 | 合理使用索引 |
| 配置优化 | 调整服务器配置 |
| 架构优化 | 优化数据模型 |
1.2 性能指标 #
| 指标 | 说明 |
|---|---|
| QPS | 每秒查询数 |
| 延迟 | 查询响应时间 |
| 吞吐量 | 数据处理量 |
| 资源使用 | CPU、内存、磁盘 |
二、查询优化 #
2.1 使用EXPLAIN分析 #
javascript
db._explain(`
FOR user IN users
FILTER user.age > 25
RETURN user
`);
2.2 查询分析输出 #
text
Query plan:
1. FOR user IN users
2. FILTER user.age > 25
3. RETURN user
Indexes used:
- none
Optimization rules applied:
- move-calculations-up
- move-filters-up
2.3 查询统计 #
javascript
var result = db._query(`
FOR user IN users
FILTER user.age > 25
RETURN user
`, {}, { profile: true });
print(result.getExtra());
2.4 常见查询优化 #
使用索引:
aql
FOR user IN users
FILTER user.email == "test@example.com"
RETURN user
限制结果:
aql
FOR user IN users
LIMIT 100
RETURN user
避免全表扫描:
aql
FOR user IN users
FILTER user._key IN @keys
RETURN user
使用投影:
aql
FOR user IN users
RETURN {
name: user.name,
email: user.email
}
2.5 子查询优化 #
aql
FOR user IN users
LET orderCount = FIRST(
FOR order IN orders
FILTER order.userId == user._key
COLLECT WITH COUNT INTO count
RETURN count
)
RETURN {
name: user.name,
orderCount: orderCount
}
三、索引优化 #
3.1 选择合适的索引类型 #
| 场景 | 推荐索引 |
|---|---|
| 等值查询 | Hash索引 |
| 范围查询 | SkipList索引 |
| 排序查询 | SkipList索引 |
| 文本搜索 | Fulltext索引 |
3.2 创建索引 #
javascript
db.users.ensureHashIndex(["email"], { unique: true });
db.orders.ensureSkipList(["createdAt"]);
db.products.ensureHashIndex(["category"]);
3.3 复合索引 #
javascript
db.orders.ensureSkipList(["userId", "createdAt"]);
查询使用复合索引:
aql
FOR order IN orders
FILTER order.userId == "user_001"
SORT order.createdAt DESC
RETURN order
3.4 索引覆盖 #
javascript
db.users.ensureHashIndex(["email", "name"]);
aql
FOR user IN users
FILTER user.email == "test@example.com"
RETURN user.name
3.5 索引监控 #
javascript
db._query(`
FOR idx IN collection_indexes
RETURN {
collection: idx.collection,
index: idx.name,
type: idx.type,
size: idx.size
}
`);
四、配置优化 #
4.1 内存配置 #
conf
[cache]
size = 25%
[rocksdb]
cache-size = 1073741824
4.2 并发配置 #
conf
[server]
endpoint = tcp://0.0.0.0:8529
threads = 8
[foxx]
queues = true
4.3 日志配置 #
conf
[log]
level = info
4.4 RocksDB配置 #
conf
[rocksdb]
max-open-files = 1000
write-buffer-size = 67108864
max-write-buffer-number = 3
五、数据模型优化 #
5.1 文档设计 #
text
优化建议:
├── 避免过度嵌套
├── 合理使用数组
├── 控制文档大小
└── 预计算常用数据
5.2 集合设计 #
text
优化建议:
├── 按访问模式分集合
├── 冷热数据分离
├── 合理设置分片
└── 使用边集合表示关系
5.3 嵌入vs引用 #
嵌入(适合一对一、一对少):
json
{
"name": "张三",
"address": {
"city": "北京",
"street": "朝阳路"
}
}
引用(适合一对多、多对多):
json
{
"name": "张三",
"orderIds": ["order_001", "order_002"]
}
六、图查询优化 #
6.1 限制遍历深度 #
aql
FOR v IN 1..2 OUTBOUND "users/user_001" follows
RETURN v
6.2 使用遍历选项 #
aql
FOR v IN 1..3 OUTBOUND "users/user_001" follows
OPTIONS {
bfs: true,
uniqueVertices: "global",
parallelism: 4
}
RETURN v
6.3 边索引 #
javascript
db.follows.ensureHashIndex(["_from"]);
db.follows.ensureHashIndex(["_to"]);
七、批量操作优化 #
7.1 批量插入 #
aql
FOR i IN 1..10000
INSERT {
name: CONCAT("用户", i),
createdAt: DATE_NOW()
} INTO users
7.2 使用事务 #
javascript
db._executeTransaction({
collections: { write: ["users"] },
action: function() {
var db = require("@arangodb").db;
for (var i = 0; i < 1000; i++) {
db.users.insert({ name: "用户" + i });
}
}
});
7.3 禁用索引后批量操作 #
javascript
db.users.dropIndex("idx_name");
db._query("FOR i IN 1..10000 INSERT { name: CONCAT('用户', i) } INTO users");
db.users.ensureHashIndex(["name"]);
八、监控与分析 #
8.1 慢查询日志 #
conf
[log]
level = info
[query]
slow-query-threshold = 5.0
8.2 查询统计 #
javascript
db._query(`
FOR q IN _queries
RETURN {
query: q.query,
runTime: q.runTime,
started: q.started
}
`);
8.3 性能指标 #
javascript
db._statistics();
8.4 集合统计 #
javascript
db.users.figures();
九、性能测试 #
9.1 基准测试 #
javascript
var start = Date.now();
for (var i = 0; i < 1000; i++) {
db._query("FOR u IN users FILTER u._key == @key RETURN u", { key: "user_" + i });
}
var end = Date.now();
print("Time: " + (end - start) + "ms");
print("QPS: " + (1000 / ((end - start) / 1000)));
9.2 并发测试 #
javascript
var threads = 10;
var queriesPerThread = 100;
var start = Date.now();
var promises = [];
for (var t = 0; t < threads; t++) {
promises.push(
db._query("FOR i IN 1..100 INSERT { value: i } INTO test")
);
}
Promise.all(promises);
var end = Date.now();
print("Total time: " + (end - start) + "ms");
十、优化案例 #
10.1 分页查询优化 #
优化前:
aql
FOR user IN users
SORT user.createdAt DESC
LIMIT 10000, 20
RETURN user
优化后:
aql
LET lastCreatedAt = @lastCreatedAt
FOR user IN users
FILTER user.createdAt < lastCreatedAt
SORT user.createdAt DESC
LIMIT 20
RETURN user
10.2 聚合查询优化 #
优化前:
aql
FOR order IN orders
COLLECT userId = order.userId AGGREGATE
total = SUM(order.amount)
RETURN { userId, total }
优化后(使用索引):
javascript
db.orders.ensureHashIndex(["userId"]);
10.3 图遍历优化 #
优化前:
aql
FOR v IN 1..10 OUTBOUND "users/user_001" follows
RETURN v
优化后:
aql
FOR v IN 1..3 OUTBOUND "users/user_001" follows
OPTIONS { uniqueVertices: "global" }
LIMIT 100
RETURN v
十一、最佳实践 #
11.1 优化检查清单 #
text
检查项:
├── 查询是否使用索引
├── 是否有不必要的全表扫描
├── 是否限制了返回结果
├── 是否使用了合适的投影
└── 是否有慢查询需要优化
11.2 性能优化流程 #
text
流程:
├── 1. 监控性能指标
├── 2. 识别性能瓶颈
├── 3. 分析查询计划
├── 4. 实施优化措施
├── 5. 验证优化效果
└── 6. 持续监控改进
十二、总结 #
性能优化要点:
- 查询优化:使用EXPLAIN分析、使用索引
- 索引优化:选择合适的索引类型
- 配置优化:调整内存、并发配置
- 数据模型优化:合理设计文档结构
- 监控分析:监控慢查询、性能指标
恭喜你完成ArangoDB完全指南的学习!
最后更新:2026-03-27