Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Pianifica i filtri della cache
Un filtro cache del piano, chiamato anche filtro di indice, limita il set di indici che il pianificatore di query è autorizzato a considerare per una specifica forma di query. Quando una query corrisponde a una forma dotata di un filtro, il planner sceglie un piano solo tra gli indici indicati in quel filtro invece di valutare tutti gli indici della raccolta.
Una forma di interrogazione è la combinazione del predicato della query, della specifica di ordinamento e dello spazio dei nomi della raccolta, con i valori del predicato normalizzati. Due query che differiscono solo nei valori condividono una forma, quindi un singolo filtro le copre tutte. Nell'output diplanCacheListFilters, i valori normalizzati sono mostrati come. "@"
Un filtro della cache del piano consente di bloccare il piano, in modo da evitare di scegliere un indice più lento a causa della distribuzione dei dati o delle modifiche all'indice. I filtri hanno le seguenti proprietà:
Non è richiesta alcuna modifica dell'applicazione. I filtri vengono impostati con un comando del database e applicati sul server, in modo da poter mitigare una regressione senza la distribuzione del codice. Questa è la differenza principale rispetto a a
hint, che deve essere aggiunta in ogni sito di chiamata.L'ambito è una forma di interrogazione. Una forma è definita dalla raccolta, dal predicato e dall'ordinamento, non dalla query completa, quindi un filtro vincola solo le query che corrispondono a quella forma. Altre interrogazioni sulla stessa raccolta continuano a essere pianificate normalmente.
Il cambiamento è duraturo. I filtri persistono durante i riavvii delle istanze e l'applicazione di patch al motore. Se si elimina la raccolta, i relativi filtri vengono rimossi.
La modifica è reversibile. La cancellazione del filtro riporta la forma alla normale pianificazione basata sui costi, quindi un filtro è un modo a basso rischio per stabilizzare un carico di lavoro mentre si analizza la causa sottostante.
Argomenti
Comandi supportati
I filtri della cache del piano richiedono la versione di Planner 2.0 o successiva. Il comando a cui è possibile applicare un filtro dipende dalla versione del planner e dalla versione secondaria di Amazon DocumentDB, come mostrato nella tabella seguente.
| Comando | Versione minima del pianificatore | Versione secondaria minima |
|---|---|---|
|
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
La versione 3.0 di Planner è disponibile solo in Amazon DocumentDB 8.0. Poiché aggregate i comandi distinct and richiedono la versione 3.0 di Planner, i filtri della cache del piano per questi due comandi sono disponibili solo in Amazon DocumentDB 8.0. In Amazon DocumentDB 5.0, che supporta la versione 2.0 di Planner, i filtri si applicano ai comandifind,,count, update e. delete findAndModify
Per il aggregate comando, la forma viene presa dalla parte anteriore della pipeline: la parte principale $match fornisce il filtro e una $sort immediatamente dopo fornisce l'ordinamento. $skipe $limit non influiscono sulla forma, così come non lo fanno gli stadi successivi a quel punto.
Amazon DocumentDB ottimizza la pipeline prima di pianificarla e un filtro della cache del piano viene confrontato con la pipeline ottimizzata. Il filtro e l'ordinamento visualizzati dal pianificatore possono quindi differire dalle fasi che hai scritto. Ad esempio, due $match fasi adiacenti nella parte anteriore di una pipeline vengono combinate in un unico $and predicato:
db.orders.aggregate([ { $match: { status: "SHIPPED" } }, { $match: { region: "us-east-1" } }, { $group: { _id: "$customerId", total: { $sum: "$amount" } } } ])
Il planner ne vede uno $match attivo{$and: [{status: ...}, {region: ...}]}, quindi il filtro deve essere impostato su quel predicato combinato.
db.runCommand({planCacheSetFilter: "orders", query: { $and: [ { status: "SHIPPED" }, { region: "us-east-1" } ] }, indexes: [ "status_1_region_1" ]})
Un filtro impostato sulla raccolta esterna di uno $graphLookup stadio $lookup o determina l'indice utilizzato per scansionare quella raccolta esterna.
Forme di interrogazione supportate
A partire da Amazon DocumentDB 5.0.2 e 8.0.2, i seguenti operatori possono apparire in una forma di query con un filtro della cache del piano:
$text. La stringa di ricerca è normalizzata, pertanto le interrogazioni che differiscono solo per i termini ricercati condividono una forma.$neare$nearSphere. Entrambi gli operatori vengono normalizzati alla stessa forma. Le coordinate$minDistance, e non$maxDistancefanno parte della forma.$geoWithine$geoIntersects. Il tipo di geometria GeoJSON fa parte della forma, quindi unaPolygonquery e un'interrogazione sono formeMultiPolygondiverse. Le coordinate non fanno parte della forma.$regex, se usato direttamente su un campo. Il modello e le opzioni sono normalizzati, quindi tutte le espressioni regolari sullo stesso campo condividono una forma.
L'impostazione di un filtro ha esito negativo e viene generato il codice di errore 303 per una forma di interrogazione che utilizza $jsonSchema$expr, o$sampleRate. Inoltre, non funziona per le seguenti forme. Un'interrogazione che ne utilizza una qualsiasi è pianificata senza filtro:
Un
$regexannidato all'interno$in,$nin, o$all. Un array che combina espressioni regolari con valori letterali non può essere valutato rispetto a un indice, quindi un filtro su quella forma non potrebbe mai essere applicato.Una specifica di ordinamento di.
{$natural: 1}Un$naturalordinamento richiede una scansione della raccolta, il che è incompatibile con la limitazione del planner a un indice.
Impostazione, elenco e cancellazione dei filtri
Per impostare un filtro della cache del piano, usa il planCacheSetFilter comando. I sort campi query e insieme specificano la forma della query ed indexes elenca i nomi di indice che il planner può prendere in considerazione per quella forma.
db.runCommand({ planCacheSetFilter: <collection>, query: <query>, sort: <sort>, // optional indexes: [ <index1>, <index2>, ...], comment: <any> // optional })
Ad esempio, il comando seguente limita il planner all'a_1indice della forma {a: {$eq: "@"}, b: {$eq: "@"}} senza alcun ordinamento:
db.runCommand({planCacheSetFilter: "foo", query: { a: 1, b: 1 }, sort: {}, indexes: [ "a_1" ]})
L'impostazione di un filtro per una forma che ne ha già uno sostituisce il filtro esistente. Dopo aver eseguito i due comandi seguenti, il filtro sulla 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" ]})
Per elencare tutti i filtri di una raccolta, usa il planCacheListFilters comando:
db.runCommand({planCacheListFilters: <collection>})
L'output mostra ogni forma memorizzata con i suoi valori normalizzati e il relativo elenco di indici consentiti:
{ "filters" : [ { "query" : { "a" : { "$eq" : "@" } }, "sort" : { }, "indexes" : [ "a_1" ] }, { "query" : { "a" : { "$gt" : "@" } }, "sort" : { "a" : 1 }, "indexes" : [ "a_1_b_1" ] } ], "ok" : 1 }
L'operatore viene preservato e solo il valore viene sostituito con"@". Un'uguaglianza implicita come {a: 1} è elencata nella sua forma esplicita e {"a": {"$eq": "@"}} gli elementi di un $in array vengono sostituiti nel loro insieme, come. {"a": {"$in": "@"}} Un set di filtri senza ordinamento viene elencato con un documento vuotosort.
Per rimuovere i filtri, utilizzare il planCacheClearFilters comando.
db.runCommand({ planCacheClearFilters: <collection>, query: <query pattern>, // optional sort: <sort specification>, // optional comment: <any> // optional })
Per cancellare tutti i filtri della raccolta, omettili entrambi query esort:
db.runCommand({planCacheClearFilters: "foo"})
Fornendo entrambiquery, sort viene cancellato solo il filtro con quell'esatto ordinamento. I valori in ingresso query vengono normalizzati, quindi qualsiasi valore rappresentativo funziona. Per cancellare solo il filtro impostato senza un ordinamento, passate un sort documento vuoto:
db.runCommand({planCacheClearFilters: "foo", query: {a: 1}, sort: {a: 1}}) db.runCommand({planCacheClearFilters: "foo", query: {a: 1}, sort: {}})
Verifica dell'applicazione di un filtro
L'explainoutput include due campi che segnalano lo stato del filtro della cache del piano:
indexFilterSetètruequando esiste un filtro nell'insieme per la forma della query.indexFilterAppliedètruesolo quando l'interrogazione è stata pianificata utilizzando un indice dall'elenco di quel filtro.
A partire da Amazon DocumentDB 5.0.2 e 8.0.2, questi campi vengono segnalati per ogni comando che supporta i filtri della cache del piano e nell'output del profiler relativo a tali comandi. Nelle versioni secondarie precedenti venivano segnalati solo per il comando. find Per ulteriori informazioni sulla lettura dell'output di explain, vedereAnalisi del piano di interrogazione.
Un filtro può corrispondere a una forma di interrogazione senza essere applicato. Se nessuno degli indici nell'elenco del filtro è in grado di soddisfare la query, il pianificatore ripianifica senza il filtro e sceglie un indice sui costi. In tal caso è ed è. indexFilterSet true indexFilterApplied false Ciò accade quando gli indici denominati non coprono i campi della query, quando gli indici denominati non esistono o quando una $regex forma non può produrre limiti di indice, ad esempio un pattern non ancorato o senza distinzione tra maiuscole e minuscole.
Esempi
Gli esempi seguenti utilizzano una orders raccolta, e nell'esempio una raccolta, con questi indici: customers $lookup
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
Esempio: aggiungere una query di ricerca a un indice composto
Considerate una query che filtra status e ordina in base a: orderDate
db.orders.find({ status: "SHIPPED" }).sort({ orderDate: 1 })
L'indice composto status_1_orderDate_1 soddisfa sia il predicato che l'ordinamento, quindi non è necessario un ordinamento separato. Se invece è il planner a sceglierestatus_1, la query deve ordinare i risultati, il che comporta un aumento di SORT livello e diventa più costoso man mano che aumenta il numero di ordini corrispondenti. Per limitare il planner all'indice composto di questa forma:
db.runCommand({planCacheSetFilter: "orders", query: { status: "SHIPPED" }, sort: { orderDate: 1 }, indexes: [ "status_1_orderDate_1" ]})
Poiché i valori sono normalizzati all'esterno della forma, questo filtro copre { status: "PENDING" } anche tutti gli altri valori status con lo stesso ordinamento. { status: "CANCELLED" } Non copre lo stesso predicato con un ordinamento diverso o con nessun ordinamento, che sono forme separate. Conferma che il filtro è entrato in vigore conexplain:
db.orders.find({ status: "SHIPPED" }).sort({ orderDate: 1 }).explain()
I report di output indexFilterSet: true indexFilterApplied: true e i nomi delle IXSCAN fasistatus_1_orderDate_1.
Esempio: aggiunta di un aggiornamento a un indice selettivo
Un aggiornamento deve individuare i documenti da modificare prima di poterli scrivere e tale ricerca utilizza un indice nello stesso modo in cui lo fa una lettura. Quando un predicato può essere servito da più di un indice, l'indice scelto dal planner determina il numero di documenti esaminati dall'aggiornamento.
db.orders.updateMany( { customerId: 4815, status: "PENDING" }, { $set: { status: "CANCELLED" } } )
Entrambi status_1 possono servire a questo customerId_1 predicato. Per aggiungere l'aggiornamento acustomerId_1:
db.runCommand({planCacheSetFilter: "orders", query: { customerId: 4815, status: "PENDING" }, indexes: [ "customerId_1" ]})
I filtri sui comandi di scrittura richiedono Amazon DocumentDB 5.0.2 o 8.0.2 e Planner versione 2.0 o successiva. Verifica con uno explain degli aggiornamenti:
db.runCommand({explain: {update: "orders", updates: [{ q: { customerId: 4815, status: "PENDING" }, u: { $set: { status: "CANCELLED" } }, multi: true }]}})
Il piano vincente è una UPDATE fase dopo l'IXSCANaltracustomerId_1. Lo stesso filtro si applica delete ai findAndModify comandi che utilizzano questa forma di interrogazione, poiché la forma non include il tipo di scrittura.
Esempio: aggiungere una pipeline aggregata e una raccolta esterna $lookup
Per un'aggregazione, la forma viene presa dalla $match fase principale e subito dopo. $sort Le fasi successive, ad esempio $group o$project, non fanno parte della forma.
db.orders.aggregate([ { $match: { status: "SHIPPED" } }, { $group: { _id: "$customerId", total: { $sum: "$amount" } } } ])
Un filtro impostato sul $match predicato determina l'indice utilizzato per leggereorders:
db.runCommand({planCacheSetFilter: "orders", query: { status: "SHIPPED" }, indexes: [ "status_1" ]})
I filtri si applicano anche alla raccolta a cui si aggiunge uno $lookup o uno $graphLookup stage. Il filtro è impostato sulla raccolta esterna, non sulla raccolta su cui viene eseguita la pipeline. Nella pipeline seguente, orders è la raccolta esterna ed customers è la raccolta esterna:
db.orders.aggregate([ { $lookup: { from: "customers", localField: "customerId", foreignField: "customerId", as: "customer" } } ])
Il join esegue una verifica customers una volta per documento esterno, quindi l'indice selezionato viene applicato ripetutamente e il relativo costo viene moltiplicato in tutta la pipeline. Per aggiungere la scansione a un indice specifico, imposta il filtro in base alla forma customers di uguaglianza della chiave di join:
db.runCommand({planCacheSetFilter: "customers", query: { customerId: 1 }, indexes: [ "customerId_1" ]})
Poiché i valori sono normalizzati a partire dalla forma, il valore 1 sopra riportato è un segnaposto e qualsiasi valore produce lo stesso filtro. Quando viene applicato un filtro di raccolta estera, il rapporto relativo true al livello superiore indexFilterSet e ai indexFilterApplied campi e l'indice selezionato dal filtro viene visualizzato sul lato esterno del piano vincente. I filtri aggregate richiedono Amazon DocumentDB 8.0.2 e Planner versione 3.0.
Comportamento con suggerimenti e modifiche all'indice
Un filtro della cache del piano ha la precedenza su un.
hintAmazon DocumentDB applica prima il filtro e poi applica il suggerimento all'interno dell'elenco degli indici consentiti del filtro. Se il suggerimento nomina un indice consentito dal filtro, viene utilizzato quell'indice. Se il suggerimento nomina un indice non consentito dal filtro, il suggerimento viene ignorato e il pianificatore sceglie tra gli indici consentiti in base ai costi. Entrambi i moduli di suggerimento si comportano allo stesso modo, sia che tu dia un nome all'indice o ne fornisca il modello chiave.Ad esempio, se la raccolta
foocontiene gli indicia_1, eb_1a_1_b_1, e si imposta un filtro sulla forma{query: {a: {$eq: "@"}, b: {$eq: "@"}}, sort: {a: 1}}con l'elenco degli indici, l'esecuzione vienedb.foo.find({ a: 10, b: 20 }).sort({a: 1}).hint({ a: 1 })utilizzata["a_1", "a_1_b_1"]a_1, poiché è denominata nel suggerimento e consentita dal filtro.L'eliminazione di un indice non modifica i filtri. Il filtro mantiene il nome dell'indice. L'indice non è presente, ma la pianificazione lo ignora. Se un altro indice nell'elenco del filtro può fornire la query, il filtro viene comunque applicato. Il rapporto viene
indexFilterAppliedgenerato solo quando nessuno degli indici denominati è disponibile.falseLa ricreazione di un indice con lo stesso nome lo rende nuovamente idoneo.L'eliminazione di una raccolta rimuove tutti i filtri della raccolta.