性能优化 #
一、性能概述 #
1.1 性能影响因素 #
text
性能影响因素:
├── 查询复杂度
├── 索引设计
├── 数据量大小
├── 网络延迟
└── 并发请求
1.2 优化目标 #
text
优化目标:
├── 降低查询延迟
├── 减少读取操作
├── 优化写入性能
├── 提高并发能力
└── 降低成本
二、查询优化 #
2.1 使用索引 #
javascript
// 好的做法:使用索引查询
Paginate(Match(Index("users_by_email"), "tom@example.com"))
// 避免:全表扫描
Filter(
Paginate(Documents(Collection("users"))),
Lambda("ref",
Equals(
Select(["data", "email"], Get(Var("ref"))),
"tom@example.com"
)
)
)
2.2 限制返回数据 #
javascript
// 限制分页大小
Paginate(
Match(Index("all_users")),
{ size: 20 }
)
// 只选择需要的字段
Map(
Paginate(Match(Index("all_users"))),
Lambda("ref",
Let(
{ doc: Get(Var("ref")) },
{
id: Select(["ref", "id"], Var("doc")),
name: Select(["data", "name"], Var("doc"))
// 只返回必要字段
}
)
)
)
2.3 使用索引覆盖 #
javascript
// 创建覆盖索引
CreateIndex({
name: "users_email_name_status",
source: Collection("users"),
terms: [
{ field: ["data", "email"] }
],
values: [
{ field: ["data", "name"] },
{ field: ["data", "status"] },
{ field: ["ref"] }
]
})
// 查询时直接获取值
Map(
Paginate(Match(Index("users_email_name_status"), "tom@example.com")),
Lambda(["name", "status", "ref"],
{
name: Var("name"),
status: Var("status")
}
)
)
2.4 避免N+1查询 #
javascript
// 好的做法:批量获取关联数据
Let(
{
orders: Paginate(Match(Index("all_orders"))),
enrichedOrders: Map(
Var("orders"),
Lambda("orderRef",
Let(
{
order: Get(Var("orderRef")),
userRef: Select(["data", "user"], Var("order")),
user: Get(Var("userRef"))
},
Merge(Var("order"), { user: Var("user") })
)
)
)
},
Var("enrichedOrders")
)
三、索引优化 #
3.1 合理设计索引 #
javascript
// 根据查询模式设计索引
CreateIndex({
name: "orders_by_user_status_date",
source: Collection("orders"),
terms: [
{ field: ["data", "userId"] },
{ field: ["data", "status"] }
],
values: [
{ field: ["data", "createdAt"], order: "desc" },
{ field: ["ref"] }
]
})
3.2 复合索引优化 #
javascript
// 一个复合索引替代多个单字段索引
CreateIndex({
name: "products_search",
source: Collection("products"),
terms: [
{ field: ["data", "categoryId"] },
{ field: ["data", "brandId"] }
],
values: [
{ field: ["data", "price"] },
{ field: ["ref"] }
]
})
3.3 部分索引 #
javascript
// 只索引需要的数据
CreateIndex({
name: "active_products",
source: {
collection: Collection("products"),
fields: {
isActive: Query(
Lambda("doc",
And(
Equals(Select(["data", "status"], Var("doc")), "active"),
GT(Select(["data", "stock"], Var("doc")), 0)
)
)
)
}
},
terms: [
{ binding: "isActive" }
]
})
3.4 索引维护 #
javascript
// 检查索引使用情况
Map(
Paginate(Indexes()),
Lambda("indexRef",
Let(
{
index: Get(Var("indexRef")),
name: Select(["name"], Var("index")),
source: Select(["source"], Var("index"))
},
{
name: Var("name"),
source: Var("source")
}
)
)
)
// 删除未使用的索引
Delete(Index("unused_index"))
四、写入优化 #
4.1 批量操作 #
javascript
// 批量创建
Map(
items,
Lambda("item",
Create(Collection("products"), {
data: Var("item")
})
)
)
// 批量更新
Foreach(
Paginate(Match(Index("users_by_status"), "pending")),
Lambda("ref",
Update(Var("ref"), {
data: { status: "active" }
})
)
)
4.2 减少历史保留 #
javascript
// 对不需要历史的集合减少保留天数
Update(Collection("logs"), {
history_days: 7
})
// 完全禁用历史
Update(Collection("temp_data"), {
history_days: 0
})
4.3 使用事务 #
javascript
// 使用Do合并多个操作
Do(
Update(userRef, { data: { balance: newBalance } }),
Create(transactions, { data: transactionData }),
Create(auditLogs, { data: logData })
)
五、缓存策略 #
5.1 应用层缓存 #
javascript
// 使用Let缓存中间结果
Let(
{
user: Get(userRef),
orders: Paginate(Match(Index("orders_by_user"), userRef))
},
{
user: Var("user"),
orderCount: Count(Var("orders"))
}
)
5.2 查询结果缓存 #
javascript
// 创建缓存集合
CreateCollection({
name: "query_cache",
ttl_days: 1
})
// 缓存查询结果
Create(Collection("query_cache"), {
data: {
queryKey: "user_stats_user_001",
result: { /* 查询结果 */ },
cachedAt: Now()
}
})
六、并发优化 #
6.1 连接池 #
javascript
// 客户端连接池配置
const { Client } = require('fauna');
const client = new Client({
secret: process.env.FAUNA_SECRET,
// 连接池设置
http2SessionIdleMs: 5000,
fetchConnectionTimeout: 10000
});
6.2 批量请求 #
javascript
// 合并多个查询
Let(
{
users: Paginate(Match(Index("all_users"))),
products: Paginate(Match(Index("all_products"))),
orders: Paginate(Match(Index("all_orders")))
},
{
users: Var("users"),
products: Var("products"),
orders: Var("orders")
}
)
七、监控与分析 #
7.1 查询分析 #
javascript
// 创建查询日志
Create(Collection("query_logs"), {
data: {
query: "users_by_email",
duration: 150,
timestamp: Now(),
params: { email: "tom@example.com" }
}
})
7.2 性能指标 #
javascript
// 收集性能指标
CreateFunction({
name: "log_query_performance",
body: Query(
Lambda(["queryName", "duration", "success"],
Create(Collection("performance_metrics"), {
data: {
query: Var("queryName"),
duration: Var("duration"),
success: Var("success"),
timestamp: Now()
}
})
)
)
})
八、实际应用示例 #
8.1 优化用户查询 #
javascript
// 优化前
Filter(
Paginate(Documents(Collection("users"))),
Lambda("ref",
And(
Equals(Select(["data", "status"], Get(Var("ref"))), "active"),
GTE(Select(["data", "age"], Get(Var("ref"))), 18)
)
)
)
// 优化后:创建合适的索引
CreateIndex({
name: "active_adult_users",
source: {
collection: Collection("users"),
fields: {
isActiveAdult: Query(
Lambda("doc",
And(
Equals(Select(["data", "status"], Var("doc")), "active"),
GTE(Select(["data", "age"], Var("doc")), 18)
)
)
)
}
},
terms: [
{ binding: "isActiveAdult" }
]
})
// 使用索引查询
Paginate(Match(Index("active_adult_users"), true))
8.2 优化订单统计 #
javascript
// 优化前:多次查询
Let(
{
total: Count(Documents(Collection("orders"))),
pending: Count(Match(Index("orders_by_status"), "pending")),
completed: Count(Match(Index("orders_by_status"), "completed")),
cancelled: Count(Match(Index("orders_by_status"), "cancelled"))
},
{ total: Var("total"), pending: Var("pending"), completed: Var("completed"), cancelled: Var("cancelled") }
)
// 优化后:单次聚合
Map(
["pending", "completed", "cancelled"],
Lambda("status",
{
status: Var("status"),
count: Count(Match(Index("orders_by_status"), Var("status")))
}
)
)
九、最佳实践 #
9.1 查询最佳实践 #
text
查询建议:
├── 始终使用索引
├── 限制返回数据量
├── 避免N+1查询
├── 使用索引覆盖
└── 批量操作
9.2 索引最佳实践 #
text
索引建议:
├── 根据查询模式设计
├── 避免过多索引
├── 使用复合索引
├── 考虑部分索引
└── 定期审查索引
9.3 写入最佳实践 #
text
写入建议:
├── 批量操作
├── 合理设置历史保留
├── 使用事务
├── 避免热点
└── 监控写入性能
十、总结 #
性能优化要点:
| 方面 | 建议 |
|---|---|
| 查询 | 使用索引、限制数据 |
| 索引 | 合理设计、定期维护 |
| 写入 | 批量操作、减少历史 |
| 缓存 | 应用缓存、查询缓存 |
| 监控 | 性能指标、查询分析 |
下一步,让我们学习监控与告警!
最后更新:2026-03-27