使用操作拒绝筛选器阻止慢速查询
8.0版本新增。
为了防止某个操作造成过多的工作负载,可以暂时拒绝与此查询结构相关联的所有操作。为此,请使用 setQuerySettings
将此操作查询结构的 reject
字段设置为 true
。被拒绝的查询结构也称为操作拒绝过滤器。
在查询规划期间,查询优化器使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。
此页面上的步骤将创建一个示例集合,并使用操作拒绝过滤器阻止查询结构。
关于此任务
假设由于应用程序的一个查询效率低下,导致集群出现过多的工作负载。为了防止查询消耗过多的集群资源,请使用操作拒绝过滤器阻止此查询和类似的查询运行。
开始之前
要识别效率低下的查询,请使用以下方法,包括:
步骤
创建示例集合
运行:
// Create pizzaOrders collection db.pizzaOrders.insertMany( [ { _id: 0, type: "pepperoni", size: "small", price: 19, totalNumber: 10, orderDate: ISODate( "2023-03-13T08:14:30Z" ) }, { _id: 1, type: "pepperoni", size: "medium", price: 20, totalNumber: 20, orderDate: ISODate( "2023-03-13T09:13:24Z" ) }, { _id: 2, type: "pepperoni", size: "large", price: 21, totalNumber: 30, orderDate: ISODate( "2023-03-17T09:22:12Z" ) }, { _id: 3, type: "cheese", size: "small", price: 12, totalNumber: 15, orderDate: ISODate( "2023-03-13T11:21:39.736Z" ) }, { _id: 4, type: "cheese", size: "medium", price: 13, totalNumber: 50, orderDate: ISODate( "2024-01-12T21:23:13.331Z" ) }, { _id: 5, type: "cheese", size: "large", price: 14, totalNumber: 10, orderDate: ISODate( "2024-01-12T05:08:13Z" ) }, { _id: 6, type: "vegan", size: "small", price: 17, totalNumber: 10, orderDate: ISODate( "2023-01-13T05:08:13Z" ) }, { _id: 7, type: "vegan", size: "medium", price: 18, totalNumber: 10, orderDate: ISODate( "2023-01-13T05:10:13Z" ) } ] )
添加操作拒绝过滤器
运行如下 setQuerySettings
命令,以添加带有以下字段的操作拒绝过滤器:
find
带有一个过滤器和一个排序,定义了查询结构。$db
数据库(为查询设置)。settings
拒绝查询结构。
db.adminCommand( { setQuerySettings: { find: "pizzaOrders", filter: { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } }, sort: { totalNumber: 1 }, $db: "test" }, settings: { reject: true } } )
截断的如下输出显示了 queryShapeHash
字段值,settings reject
字段为 true
:
{ queryShapeHash: 'AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1', settings: { reject: true }, representativeQuery: { find: 'pizzaOrders', filter: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, sort: { totalNumber: 1 }, '$db': 'test' }, ok: 1, ... }
(可选)使用解释命令确认设置
运行 explain
:
db.pizzaOrders.explain().find( { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )
截断的如下输出表明,querySettings reject
字段为 true
:
{ queryPlanner: { winningPlan: { stage: 'SINGLE_SHARD', shards: [ { explainVersion: '1', ... namespace: 'test.pizzaOrders', parsedQuery: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, querySettings: { reject: true }, ... } ] } }
(可选)删除操作拒绝过滤器
如下示例使用 removeQuerySettings
删除操作拒绝过滤器,此过滤器由前面的第 2 步中所示的输出中的 queryShapeHash
值识别:
db.adminCommand( { removeQuerySettings: "AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1" } )
也可以从以下位置获取 queryShapeHash
值:
也可以使用查询结构删除操作拒绝过滤器。例如:
db.adminCommand( { removeQuerySettings: { find: "pizzaOrders", filter: { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } }, sort: { totalNumber: 1 }, $db: "test" } } )
后续步骤
使用操作拒绝过滤器阻止低效操作之后,集群性能应当恢复到引入低效查询之前的状态。后续步骤:
解决查询性能问题。这可能需要执行索引或重写查询。
部署更新后的应用程序。
要重新启用未删除的查询设置,请使用 setQuerySettings
并将 reject
字段设置为 false
。