面试题答案
一键面试1. 分片键选择
- 选择离散性好的字段:对于跨数据库和集合的联合查询,应选在多个集合中都能均匀分布数据的字段作为分片键。例如,如果联合查询经常涉及订单集合和客户集合,且订单按客户ID分布较为均匀,那么客户ID可作为分片键。这样能确保数据在各个分片上均匀分布,避免热点分片。
- 避免使用单调递增字段:像时间戳、自增ID这类单调递增字段不适合做分片键,因为新数据会持续写入到同一个分片,导致该分片负载过高,影响查询性能。
2. 索引策略
- 创建复合索引:针对跨数据库和集合的联合查询条件,创建复合索引。例如,若查询条件是订单日期和客户等级,可创建包含这两个字段的复合索引
{order_date: 1, customer_level: 1}
。复合索引能显著提高查询效率,但要注意索引字段顺序,将选择性高的字段放在前面。 - 覆盖索引:尽量使用覆盖索引,即查询所需的所有字段都包含在索引中。这样MongoDB无需回表查询文档,直接从索引中获取数据,大大提高查询性能。例如,查询只需要订单ID和订单金额,可创建索引
{order_id: 1, order_amount: 1}
。
3. 查询优化
- 减少跨分片查询:在设计查询时,尽量将查询条件限制在单个分片或少数分片上。如果可能,使用基于分片键的查询,让查询能直接定位到特定分片,减少跨分片数据传输开销。
- 使用聚合框架:对于复杂的联合查询,聚合框架能在数据库端高效处理数据。例如,使用
$lookup
操作符进行跨集合关联,结合$match
、$group
等操作符进行数据过滤和聚合,通过合理优化聚合管道步骤提升查询性能。 - 批量操作:尽量避免多次小查询,将多个查询合并为批量操作。例如,使用
$in
操作符一次查询多个条件,减少网络开销和查询次数。