性能优化 #

一、性能概述 #

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