面试题答案
一键面试创建视图索引提升查询性能
- 设计原则
- 理解业务查询需求:深入了解应用程序将如何查询CouchDB中的数据。确定哪些字段组合会频繁用于查询,例如在电商应用中,可能经常根据商品类别、价格范围等组合条件查询商品文档。
- 避免过度索引:虽然索引能提升查询性能,但过多索引会增加存储开销和写入操作的性能损耗。只创建必要的索引。
- 创建视图索引步骤
- 定义Map函数:在CouchDB中,视图索引由MapReduce函数定义,其中Map函数是必需的。Map函数会遍历文档集合,对每个文档进行处理。例如,如果要根据“category”和“price”字段查询文档,Map函数可能如下:
function (doc) {
if (doc.category && doc.price) {
emit([doc.category, doc.price], null);
}
}
这里将“category”和“price”组成数组作为键(key),值(value)可以根据需求设置,这里设为null
。
- 发布视图:将包含Map函数(可能还有Reduce函数,如果需要聚合操作)的设计文档发布到CouchDB数据库。设计文档通常放在_design
目录下,例如/_design/views/_view/my_view
。
查询特定字段组合文档时索引设计要点
- 字段顺序:在Map函数的
emit
中,字段顺序至关重要。CouchDB的视图索引是有序的,查询时会按照索引中字段的顺序进行匹配。例如,如果查询条件是先按“category”过滤,再按“price”过滤,那么emit([doc.category, doc.price], null)
这样的顺序是合适的。如果顺序颠倒,查询性能可能不佳。 - 复合索引与前缀匹配:对于复合索引(多个字段组成的索引),CouchDB支持前缀匹配。例如,对于索引
[category, price]
,如果只查询特定“category”的文档,CouchDB可以利用这个索引。但如果只查询特定“price”的文档(没有“category”条件),这个索引就无法有效利用。所以在设计复合索引时,要考虑查询的灵活性和最常见的查询模式。 - 使用Reduce函数:如果查询需要对匹配的文档进行聚合操作,如计算总数、求和等,可以定义Reduce函数。例如,要计算每个“category”下商品的平均价格,可以定义如下Reduce函数:
function (keys, values, rereduce) {
if (rereduce) {
return values.reduce(function (sum, value) {
return sum + value;
}, 0) / values.length;
} else {
return values.length;
}
}
在查询时,结合Map和Reduce函数可以高效地得到所需的聚合结果。