使用操作拒绝过滤器阻止慢查询
新增在版本中8.0.
为了防止操作导致过大的工作负载,您可以暂时拒绝与该操作相关的所有操作。要实现这一点,请使用 查询形状。为此,使用 setQuerySettings
将操作的查询形状的 reject
字段设置为 true
。被拒绝的查询形状也称为 操作拒绝过滤器。
查询优化器在查询规划期间将查询设置作为附加输入,这会影响选择运行的查询计划。
本页上的步骤创建了一个示例集合,并使用操作拒绝过滤器来阻止查询形状。
关于此任务
假设一个集群由于应用程序的查询效率低下而有过大的工作负载。为了防止查询消耗过多的集群资源,请使用操作拒绝过滤器来阻止查询及其类似查询的运行。
在开始之前
要识别低效查询,请使用包括以下方法在内的各种方法:
步骤
1
创建示例集合
运行
// 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" ) } ] )
2
添加操作拒绝过滤器
运行以下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, ... }
3
(可选) 使用 explain 命令来确认设置
运行 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 }, ... } ] } }
4
5
(可选) 删除操作拒绝过滤器
以下示例使用 removeQuerySettings
删除操作拒绝过滤器,这些过滤器使用步骤 2 中显示的输出中的 queryShapeHash
值识别
db.adminCommand( { removeQuerySettings: "AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1" } )
您还可以从
您还可以使用查询形状删除操作拒绝过滤器。例如
db.adminCommand( { removeQuerySettings: { find: "pizzaOrders", filter: { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } }, sort: { totalNumber: 1 }, $db: "test" } } )
下一步操作
在您使用操作拒绝过滤器阻止低效操作后,您的集群性能应恢复到引入低效查询之前的状态。下一步操作
解决查询的性能问题。这可能需要索引或查询重写。
部署更新后的应用程序。
要重新启用未删除的查询设置,请使用 setQuerySettings
并将 reject
字段设置为 false
。