As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Planejar filtros de cache
Um filtro de cache de plano, também chamado de filtro de índice, restringe o conjunto de índices que o planejador de consultas pode considerar para uma forma de consulta específica. Quando uma consulta corresponde a uma forma que tem um filtro, o planejador escolhe um plano somente a partir dos índices nomeados nesse filtro, em vez de avaliar cada índice na coleção.
Uma forma de consulta é a combinação do predicado da consulta, da especificação de classificação e do namespace da coleção, com os valores do predicado normalizados. Duas consultas que diferem apenas em seus valores compartilham uma forma, portanto, um único filtro cobre todas elas. Na saída deplanCacheListFilters, os valores normalizados são mostrados como"@".
Um filtro de cache do plano oferece uma maneira de fixar o plano, para que você possa evitar escolher um índice mais lento devido à distribuição de dados ou às alterações no índice. Os filtros têm as seguintes propriedades:
Nenhuma alteração no aplicativo é necessária. Os filtros são definidos com um comando de banco de dados e aplicados no servidor, para que você possa mitigar uma regressão sem uma implantação de código. Essa é a principal diferença de um
hint, que deve ser adicionado em cada site de chamada.O escopo é uma forma de consulta. Uma forma é definida pela coleção, pelo predicado e pela classificação, não pela consulta completa, portanto, um filtro restringe somente as consultas que correspondem a essa forma. Outras consultas sobre a mesma coleção continuam sendo planejadas normalmente.
A mudança é durável. Os filtros persistem durante a reinicialização da instância e a correção do mecanismo. Descartar a coleção remove seus filtros.
A mudança é reversível. Limpar o filtro retorna ao planejamento normal baseado em custos, portanto, um filtro é uma forma de baixo risco de estabilizar uma carga de trabalho enquanto você investiga a causa subjacente.
Tópicos
Comandos compatíveis
Os filtros de cache do plano exigem a versão 2.0 ou posterior do planejador. O comando ao qual um filtro pode ser aplicado depende da versão do planejador e da versão secundária do Amazon DocumentDB, conforme mostrado na tabela a seguir.
| Command | Versão mínima do planejador | Versão secundária mínima |
|---|---|---|
|
2,0 |
5.0.0, 8.0.0 |
|
2,0 |
5.0.0, 8.0.0 |
|
2,0 |
5.0.2, 8.0.2 |
|
2,0 |
5.0.2, 8.0.2 |
|
2,0 |
5.0.2, 8.0.2 |
|
3.0 |
8.0.0 |
|
3.0 |
8.0.2 |
nota
A versão 3.0 do Planner está disponível somente no Amazon DocumentDB 8.0. Como os aggregate comandos distinct e exigem a versão 3.0 do planejador, os filtros de cache do plano para esses dois comandos estão disponíveis somente no Amazon DocumentDB 8.0. No Amazon DocumentDB 5.0, que oferece suporte à versão 2.0 do planejador, os filtros se aplicam aos count comandosfind,update,delete, e. findAndModify
Para o aggregate comando, a forma é obtida da frente da tubulação: a tubulação $match fornece o filtro e a $sort imediatamente depois fornece a classificação. $skipe $limit não afetam a forma, nem os estágios além desse ponto.
O Amazon DocumentDB otimiza o pipeline antes de planejá-lo, e um filtro de cache do plano é comparado ao pipeline otimizado. O filtro e a classificação que o planejador vê podem, portanto, diferir dos estágios que você escreveu. Por exemplo, dois $match estágios adjacentes na frente de um pipeline são combinados em um único $and predicado:
db.orders.aggregate([ { $match: { status: "SHIPPED" } }, { $match: { region: "us-east-1" } }, { $group: { _id: "$customerId", total: { $sum: "$amount" } } } ])
O planejador vê um $match ativado{$and: [{status: ...}, {region: ...}]}, então o filtro precisa ser definido nesse predicado combinado.
db.runCommand({planCacheSetFilter: "orders", query: { $and: [ { status: "SHIPPED" }, { region: "us-east-1" } ] }, indexes: [ "status_1_region_1" ]})
Um filtro definido na coleção externa de um $graphLookup estágio $lookup ou conduz o índice usado para escanear essa coleção externa.
Formas de consulta suportadas
A partir do Amazon DocumentDB 5.0.2 e 8.0.2, os seguintes operadores podem aparecer em uma forma de consulta que tenha um filtro de cache de plano:
$text. A string de pesquisa é normalizada, portanto, as consultas que diferem apenas nos termos pesquisados compartilham uma forma.$neare$nearSphere. Ambos os operadores se normalizam para a mesma forma. As coordenadas$minDistance, e não$maxDistancefazem parte da forma.$geoWithine$geoIntersects. O tipo de geometria GeoJSON faz parte da forma, portanto, umaPolygonconsulta e umaMultiPolygonconsulta têm formas diferentes. As coordenadas não fazem parte da forma.$regex, quando usado diretamente em um campo. O padrão e as opções são normalizados, então todas as expressões regulares no mesmo campo compartilham a mesma forma.
A configuração de um filtro falha com o código de erro 303 para uma forma de consulta que usa$jsonSchema,$expr, ou$sampleRate. Ele também falha nas seguintes formas. Uma consulta que usa qualquer uma delas é planejada sem um filtro:
Um
$regexaninhado dentro$in,$nin, ou$all. Uma matriz que mistura expressões regulares com valores literais não pode ser avaliada em relação a um índice, portanto, um filtro nessa forma nunca poderia ser aplicado.Uma espécie de especificação de
{$natural: 1}. Uma$naturalclassificação solicita uma varredura de coleção, o que é incompatível com a restrição do planejador a um índice.
Configurando, listando e limpando filtros
Para definir um filtro de cache do plano, use o planCacheSetFilter comando. Juntos, sort os campos query e especificam a forma da consulta e indexes listam os nomes dos índices que o planejador pode considerar para essa forma.
db.runCommand({ planCacheSetFilter: <collection>, query: <query>, sort: <sort>, // optional indexes: [ <index1>, <index2>, ...], comment: <any> // optional })
Por exemplo, o comando a seguir restringe o planejador ao a_1 índice da forma {a: {$eq: "@"}, b: {$eq: "@"}} sem classificação:
db.runCommand({planCacheSetFilter: "foo", query: { a: 1, b: 1 }, sort: {}, indexes: [ "a_1" ]})
Definir um filtro para uma forma que já tem um substitui o filtro existente. Depois de executar os dois comandos a seguir, o filtro na forma {a: {$eq: "@"}, b: {$eq: "@"}} é["b_1"]:
db.runCommand({planCacheSetFilter: "foo", query: { a: 1, b: 1 }, sort: {}, indexes: [ "a_1" ]}) db.runCommand({planCacheSetFilter: "foo", query: { a: 6, b: 10 }, sort: {}, indexes: [ "b_1" ]})
Para listar todos os filtros em uma coleção, use o planCacheListFilters comando:
db.runCommand({planCacheListFilters: <collection>})
A saída mostra cada forma armazenada com seus valores normalizados e sua lista de índices permitidos:
{ "filters" : [ { "query" : { "a" : { "$eq" : "@" } }, "sort" : { }, "indexes" : [ "a_1" ] }, { "query" : { "a" : { "$gt" : "@" } }, "sort" : { "a" : 1 }, "indexes" : [ "a_1_b_1" ] } ], "ok" : 1 }
O operador é preservado e somente o valor é substituído por"@". Uma igualdade implícita, como a, {a: 1} {"a": {"$eq": "@"}} está listada em sua forma explícita e os elementos de uma $in matriz são substituídos como um todo, como. {"a": {"$in": "@"}} Um conjunto de filtros sem classificação é listado com um sort documento vazio.
Para remover filtros, use o planCacheClearFilters comando.
db.runCommand({ planCacheClearFilters: <collection>, query: <query pattern>, // optional sort: <sort specification>, // optional comment: <any> // optional })
Para limpar todos os filtros da coleção, omita ambos query esort:
db.runCommand({planCacheClearFilters: "foo"})
Fornecer ambos query e sort limpar somente o filtro que tem esse tipo exato. Os valores em query são normalizados, portanto, qualquer valor representativo funciona. Para limpar somente o filtro que foi definido sem uma classificação, passe um sort documento vazio:
db.runCommand({planCacheClearFilters: "foo", query: {a: 1}, sort: {a: 1}}) db.runCommand({planCacheClearFilters: "foo", query: {a: 1}, sort: {}})
Verificando se um filtro foi aplicado
A explain saída inclui dois campos que relatam o status do filtro de cache do plano:
indexFilterSetétruequando existe um filtro na coleção para a forma da consulta.indexFilterAppliedétruesomente quando a consulta foi planejada usando um índice da lista desse filtro.
A partir do Amazon DocumentDB 5.0.2 e 8.0.2, esses campos são relatados para cada comando que suporta filtros de cache de plano e na saída do profiler para esses comandos. Nas versões secundárias anteriores, eles eram relatados apenas para o find comando. Para obter mais informações sobre como ler a saída de explicação, consulteAnálise do plano de consulta.
Um filtro pode corresponder a uma forma de consulta sem ser aplicado. Se nenhum dos índices na lista do filtro puder atender à consulta, o planejador planeja novamente sem o filtro e escolhe um índice de custo. Nesse caso, indexFilterSet é true e indexFilterApplied éfalse. Isso acontece quando os índices nomeados não cobrem os campos da consulta, quando os índices nomeados não existem ou quando uma $regex forma não pode produzir limites de índice, como um padrão não ancorado ou que não diferencia maiúsculas de minúsculas.
Exemplos
Os exemplos a seguir usam uma orders coleção e uma customers coleção para o $lookup exemplo com esses índices:
db.orders.createIndex({ status: 1 }) // status_1 db.orders.createIndex({ status: 1, orderDate: 1 }) // status_1_orderDate_1 db.orders.createIndex({ customerId: 1 }) // customerId_1 db.customers.createIndex({ customerId: 1 }) // customerId_1
Exemplo: fixar uma consulta de busca em um índice composto
Considere uma consulta que filtra status e classifica pororderDate:
db.orders.find({ status: "SHIPPED" }).sort({ orderDate: 1 })
O índice composto status_1_orderDate_1 satisfaz tanto o predicado quanto a classificação, portanto, nenhuma classificação separada é necessária. Se o planejador preferirstatus_1, a consulta precisará classificar seus resultados, o que adiciona um SORT estágio e fica mais caro à medida que o número de pedidos correspondentes aumenta. Para restringir o planejador ao índice composto dessa forma:
db.runCommand({planCacheSetFilter: "orders", query: { status: "SHIPPED" }, sort: { orderDate: 1 }, indexes: [ "status_1_orderDate_1" ]})
Como os valores são normalizados fora da forma, esse filtro também cobre{ status: "PENDING" },{ status: "CANCELLED" }, e todos os outros valores status com o mesmo tipo. Ele não cobre o mesmo predicado com um tipo diferente, ou sem classificação, que são formas separadas. Confirme se o filtro entrou em vigor comexplain:
db.orders.find({ status: "SHIPPED" }).sort({ orderDate: 1 }).explain()
Os relatórios de saída indexFilterSet: true eindexFilterApplied: true, e os nomes IXSCAN artísticosstatus_1_orderDate_1.
Exemplo: fixar uma atualização em um índice seletivo
Uma atualização precisa localizar os documentos a serem modificados antes de poder gravá-los, e essa pesquisa usa um índice da mesma forma que uma leitura. Quando um predicado pode ser servido por mais de um índice, o índice escolhido pelo planejador determina quantos documentos a atualização examina.
db.orders.updateMany( { customerId: 4815, status: "PENDING" }, { $set: { status: "CANCELLED" } } )
Ambos customerId_1 status_1 podem servir a esse predicado. Para fixar a atualização emcustomerId_1:
db.runCommand({planCacheSetFilter: "orders", query: { customerId: 4815, status: "PENDING" }, indexes: [ "customerId_1" ]})
Os filtros nos comandos de gravação exigem o Amazon DocumentDB 5.0.2 ou 8.0.2 e o planner versão 2.0 ou posterior. Verifique com uma explain das atualizações:
db.runCommand({explain: {update: "orders", updates: [{ q: { customerId: 4815, status: "PENDING" }, u: { $set: { status: "CANCELLED" } }, multi: true }]}})
O plano vencedor é um UPDATE estágio IXSCAN em vez de umcustomerId_1. O mesmo filtro se aplica a findAndModify comandos delete e comandos que usam essa forma de consulta, porque a forma não inclui o tipo de gravação.
Exemplo: fixar um pipeline agregado e uma coleção estrangeira $lookup
Para uma agregação, a forma é retirada do $match palco principal e $sort imediatamente após ele. Estágios além desse, como $group ou$project, não fazem parte da forma.
db.orders.aggregate([ { $match: { status: "SHIPPED" } }, { $group: { _id: "$customerId", total: { $sum: "$amount" } } } ])
Um filtro definido no $match predicado direciona o índice usado para ler: orders
db.runCommand({planCacheSetFilter: "orders", query: { status: "SHIPPED" }, indexes: [ "status_1" ]})
Os filtros também se aplicam à coleção à qual um $graphLookup estágio $lookup ou estágio se junta. O filtro é colocado na coleção externa, não na coleção contra a qual a tubulação passa. No pipeline a seguir, orders é a coleção externa e customers é a coleção externa:
db.orders.aggregate([ { $lookup: { from: "customers", localField: "customerId", foreignField: "customerId", as: "customer" } } ])
A junção sonda customers uma vez por documento externo, então o índice escolhido é aplicado repetidamente e seu custo é multiplicado em todo o pipeline. Para fixar esse escaneamento em um índice específico, ative o filtro customers para a forma de igualdade da chave de junção:
db.runCommand({planCacheSetFilter: "customers", query: { customerId: 1 }, indexes: [ "customerId_1" ]})
Como os valores são normalizados fora da forma, o valor 1 acima é um espaço reservado e qualquer valor produz o mesmo filtro. Quando um filtro de cobrança estrangeira é aplicado, o nível superior indexFilterSet e os indexFilterApplied campos são relatadostrue, e o índice selecionado pelo filtro aparece no lado externo do plano vencedor. Os filtros ativados aggregate exigem o Amazon DocumentDB 8.0.2 e a versão 3.0 do planejador.
Comportamento com dicas e alterações no índice
Um filtro de cache de plano tem precedência sobre um
hint. O Amazon DocumentDB aplica o filtro primeiro e depois aplica a dica na lista de índices permitidos do filtro. Se a dica nomear um índice permitido pelo filtro, esse índice será usado. Se a dica nomear um índice que o filtro não permite, a dica será ignorada e o planejador escolherá entre os índices permitidos de acordo com o custo. As duas formas de dica se comportam da mesma maneira, independentemente de você nomear o índice ou fornecer seu padrão de chave.Por exemplo, se a coleção
footiver os índices, ea_1b_1a_1_b_1, e você definir um filtro na forma{query: {a: {$eq: "@"}, b: {$eq: "@"}}, sort: {a: 1}}com a lista de índices["a_1", "a_1_b_1"], a execuçãodb.foo.find({ a: 10, b: 20 }).sort({a: 1}).hint({ a: 1 })usaráa_1, pois ela é nomeada na dica e permitida pelo filtro.A eliminação de um índice não modifica os filtros. O filtro mantém o nome do índice. Embora esse índice esteja ausente, o planejamento o ignora. Se outro índice na lista do filtro puder servir à consulta, o filtro ainda será aplicado. Somente quando nenhum dos índices nomeados está disponível é que o
indexFilterAppliedrelatóriofalseé feito. Recriar um índice com o mesmo nome o torna elegível novamente.Eliminar uma coleção remove todos os filtros dessa coleção.