作为Woovi量表,我们有越来越多的电荷和交易。费用代表付款请求,交易代表我们的商家银行帐户中的移动。我们的MongoDB数据库中的这两个集合非常大,而且仍然非常快。
确保我们不会推出引起COLLSCAN
的新代码(阅读整个表),我们始终需要确保我们的查询使用适当的索引。
了解mongodb解释输出
我们首先需要了解MongoDB如何计划其查询。
为此,我们将使用命令db.collection.explain()
,您可以在MongoDB docs
它可以有5种不同的操作:
-
COLLSCAN
用于收集扫描 -
IXSCAN
用于扫描索引键 -
FETCH
用于检索文档 -
GROUP
用于分组文档 -
SHARD_MERGE
合并碎片结果 -
SHARDING_FILTER
用于从碎片中过滤孤儿文档
COLLSCAN
是最糟糕的情况,因为它需要扫描整个系列以查找一个项目,也就是o(n),对于像我们这样的大型收藏很慢。
IXSCAN
是最好的操作,因为它在最坏的情况下使用索引平衡的b-tree(log(log(n))
FETCH
是在他们需要检索更多文档的时候,用于分页
SHARD_MERGE
是您有共享数据库的时候,需要合并一些碎片的结果
SHARDING_FILTER
是您需要在碎片中过滤数据的时候。
自动化IXSCAN索引测试
我们在测试中使用内存中的mongoDB来确保我们的代码在数据库中执行正确的查询和聚合。这避免了嘲笑数据库时发生的许多假阳性和假否定。
当我们使用真实的mongoDB时,我们可以在执行查找或汇总时调用.explain()
方法,而mongodb将返回查询计划者,显示数据库将如何执行查询的获胜计划。
检查我们查询是否使用索引的测试,在mongodb中称为IXSCAN
,非常简单:
const getStageFromExplanation = (explanation: MongoExplanation) =>
explanation.queryPlanner.winningPlan.inputStage.stage;
it('should test the ixscan from myquery', async () => {
// force model index creation
await Model.syncIndexes();
// create your test query
const modelCursor = Model.find({
name: 'Edu',
age: '18',
});
// ask to explain
modelCursor.explain();
// wait for explanation
const modelExplained = await modelCursor;
//check if the query explanation uses index - IXSCAN
expect(getStageFromExplanation(modelExplained)).toEqual('IXSCAN');
});
我们执行查找,要求使用.explain
方法进行解释,然后在查询计划者的获胜计划中检查IXSCAN。
总结
随着扩展的规模,您的数据库变得越来越重要,因此您无法将新代码推向使用CollScan或进行缓慢查询的生产。
在Woovi,我们对此性能检查进行自动化,以确保在将新代码推向生产之前使用适当的索引。
我们还在分期和生产环境中使用Kibana和Elastic APM监测性能回归。
参考
woi
Woovi是一家创业公司,使购物者能够按照自己的意愿付款。为了实现这一目标,Woovi为商人提供即时付款解决方案接受订单。
如果您想与我们合作,我们是hiring!
Shiro hatori在Unsplash上的照片