Docs 菜单
Docs 主页
/
MongoDB Manual
/ / / /

使用操作拒绝筛选器阻止慢速查询

在此页面上

  • 关于此任务
  • 开始之前
  • 步骤
  • 后续步骤
  • 了解详情

8.0版本新增

为了防止某个操作造成过多的工作负载,可以暂时拒绝与此查询结构相关联的所有操作。为此,请使用 setQuerySettings 将此操作查询结构的 reject 字段设置为 true。被拒绝的查询结构也称为操作拒绝过滤器

在查询规划期间,查询优化器使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。

此页面上的步骤将创建一个示例集合,并使用操作拒绝过滤器阻止查询结构。

假设由于应用程序的一个查询效率低下,导致集群出现过多的工作负载。为了防止查询消耗过多的集群资源,请使用操作拒绝过滤器阻止此查询和类似的查询运行。

要识别效率低下的查询,请使用以下方法,包括:

  • Atlas 监控

  • atlas alerts

  • Atlas 查询分析器

  • 慢查询日志

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

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

尝试运行此查询:

db.pizzaOrders.find( { orderDate: {
$gt: ISODate("2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )

如下输出将确认查询被拒绝:

MongoServerError: Query rejected by admin query settings
5

如下示例使用 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"
}
} )
6

由于删除了操作拒绝过滤器,如下查询已被取消阻止,并且现在正在运行:

db.pizzaOrders.find( { orderDate: {
$gt: ISODate("2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )

使用操作拒绝过滤器阻止低效操作之后,集群性能应当恢复到引入低效查询之前的状态。后续步骤:

  1. 解决查询性能问题。这可能需要执行索引或重写查询。

  2. 部署更新后的应用程序。

要重新启用未删除的查询设置,请使用 setQuerySettings 并将 reject 字段设置为 false

后退

输出