Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Rencanakan filter cache
Filter cache rencana, juga disebut filter indeks, membatasi kumpulan indeks yang diperbolehkan dipertimbangkan oleh perencana kueri untuk bentuk kueri tertentu. Ketika kueri cocok dengan bentuk yang memiliki filter, perencana memilih rencana hanya dari indeks yang disebutkan dalam filter itu alih-alih mengevaluasi setiap indeks pada koleksi.
Bentuk kueri adalah kombinasi dari predikat kueri, spesifikasi pengurutan, dan namespace koleksi, dengan nilai predikat dinormalisasi. Dua kueri yang berbeda hanya dalam nilainya berbagi bentuk, sehingga satu filter mencakup semuanya. Dalam output dariplanCacheListFilters, nilai yang dinormalisasi ditampilkan sebagai"@".
Filter cache paket memberi Anda cara untuk menyematkan paket, sehingga Anda dapat menghindari memilih indeks yang lebih lambat karena distribusi data atau perubahan indeks. Filter memiliki properti berikut:
Tidak diperlukan perubahan aplikasi. Filter diatur dengan perintah database dan diterapkan pada server, sehingga Anda dapat mengurangi regresi tanpa penerapan kode. Ini adalah perbedaan utama dari a
hint, yang harus ditambahkan di setiap situs panggilan.Cakupan adalah satu bentuk kueri. Bentuk ditentukan oleh koleksi, predikat, dan pengurutan, bukan oleh kueri lengkap, sehingga filter hanya membatasi kueri yang cocok dengan bentuk itu. Pertanyaan lain pada koleksi yang sama terus direncanakan secara normal.
Perubahannya tahan lama. Filter tetap ada di seluruh restart instans dan tambalan mesin. Menjatuhkan koleksi akan menghapus filternya.
Perubahan itu reversibel. Menghapus filter mengembalikan bentuk ke perencanaan berbasis biaya normal, sehingga filter adalah cara berisiko rendah untuk menstabilkan beban kerja saat Anda menyelidiki penyebab yang mendasarinya.
Topik
Perintah yang Didukung
Filter cache rencana memerlukan perencana versi 2.0 atau yang lebih baru. Perintah yang dapat diterapkan filter tergantung pada versi perencana dan versi minor Amazon DocumentDB, seperti yang ditunjukkan pada tabel berikut.
| Perintah | Versi perencana minimum | Versi minor minimum |
|---|---|---|
|
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 |
catatan
Planner versi 3.0 hanya tersedia di Amazon DocumentDB 8.0. Karena aggregate perintah distinct and memerlukan planner versi 3.0, filter cache rencana untuk kedua perintah tersebut hanya tersedia di Amazon DocumentDB 8.0. Di Amazon DocumentDB 5.0, yang mendukung perencana versi 2.0, filter berlaku untuk findAndModify perintahfind,count,update,delete, dan.
Untuk aggregate perintah, bentuknya diambil dari bagian depan pipa: bagian depan $match memasok filter, dan $sort segera setelah itu memasok jenis. $skipdan $limit tidak mempengaruhi bentuk, dan juga tahapan di luar titik itu.
Amazon DocumentDB mengoptimalkan pipeline sebelum merencanakannya, dan filter cache rencana dicocokkan dengan pipeline yang dioptimalkan. Oleh karena itu, filter dan pengurutan yang dilihat perencana dapat berbeda dari tahapan yang Anda tulis. Misalnya, dua $match tahap yang berdekatan di depan pipa digabungkan menjadi satu $and predikat:
db.orders.aggregate([ { $match: { status: "SHIPPED" } }, { $match: { region: "us-east-1" } }, { $group: { _id: "$customerId", total: { $sum: "$amount" } } } ])
Perencana melihat satu $match aktif{$and: [{status: ...}, {region: ...}]}, jadi filter harus diatur pada predikat gabungan itu.
db.runCommand({planCacheSetFilter: "orders", query: { $and: [ { status: "SHIPPED" }, { region: "us-east-1" } ] }, indexes: [ "status_1_region_1" ]})
Filter yang ditetapkan pada koleksi asing dari pang $graphLookup gung $lookup atau mendorong indeks yang digunakan untuk memindai koleksi asing itu.
Bentuk kueri yang didukung
Dimulai dengan Amazon DocumentDB 5.0.2 dan 8.0.2, operator berikut dapat muncul dalam bentuk kueri yang memiliki filter cache paket:
$text. String pencarian dinormalisasi, sehingga kueri yang berbeda hanya dalam istilah yang mereka cari berbagi satu bentuk.$neardan$nearSphere. Kedua operator menormalkan ke bentuk yang sama. Koordinat$minDistance,, dan$maxDistancebukan bagian dari bentuk.$geoWithindan$geoIntersects. Jenis geometri GeoJSON adalah bagian dari bentuk, jadiPolygonkueri dan kueri adalahMultiPolygonbentuk yang berbeda. Koordinat bukan bagian dari bentuk.$regex, bila digunakan langsung di lapangan. Pola dan opsi dinormalisasi, sehingga semua ekspresi reguler pada bidang yang sama berbagi satu bentuk.
Menyetel filter gagal dengan kode kesalahan 303 untuk bentuk kueri yang menggunakan$jsonSchema,$expr, atau$sampleRate. Itu juga gagal untuk bentuk-bentuk berikut. Kueri yang menggunakan salah satu dari mereka direncanakan tanpa filter:
Sebuah ber
$regexsarang di dalam$in,$nin, atau$all. Array yang mencampur ekspresi reguler dengan nilai literal tidak dapat dievaluasi terhadap indeks, sehingga filter pada bentuk itu tidak pernah dapat diterapkan.Semacam spesifikasi
{$natural: 1}. Pen$naturalyortiran meminta pemindaian koleksi, yang tidak sesuai dengan membatasi perencana ke indeks.
Menyetel, mencantumkan, dan menghapus filter
Untuk mengatur filter cache rencana, gunakan planCacheSetFilter perintah. sortBid query ang dan bersama-sama menentukan bentuk kueri, dan indexes mencantumkan nama indeks yang diperbolehkan dipertimbangkan oleh perencana untuk bentuk itu.
db.runCommand({ planCacheSetFilter: <collection>, query: <query>, sort: <sort>, // optional indexes: [ <index1>, <index2>, ...], comment: <any> // optional })
Misalnya, perintah berikut membatasi perencana ke a_1 indeks untuk bentuk {a: {$eq: "@"}, b: {$eq: "@"}} tanpa pengurutan:
db.runCommand({planCacheSetFilter: "foo", query: { a: 1, b: 1 }, sort: {}, indexes: [ "a_1" ]})
Menyetel filter untuk bentuk yang sudah memilikinya menggantikan filter yang ada. Setelah menjalankan dua perintah berikut, filter pada bentuknya {a: {$eq: "@"}, b: {$eq: "@"}} adalah["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" ]})
Untuk mencantumkan setiap filter pada koleksi, gunakan planCacheListFilters perintah:
db.runCommand({planCacheListFilters: <collection>})
Output menunjukkan setiap bentuk yang disimpan dengan nilai yang dinormalisasi dan daftar indeks yang diizinkan:
{ "filters" : [ { "query" : { "a" : { "$eq" : "@" } }, "sort" : { }, "indexes" : [ "a_1" ] }, { "query" : { "a" : { "$gt" : "@" } }, "sort" : { "a" : 1 }, "indexes" : [ "a_1_b_1" ] } ], "ok" : 1 }
Operator dipertahankan dan hanya nilai yang diganti dengan"@". Kesetaraan implisit seperti {a: 1} terdaftar dalam bentuk eksplisitnya{"a": {"$eq": "@"}},, dan elemen $in -elemen array diganti secara keseluruhan, sebagai{"a": {"$in": "@"}}. Kumpulan filter tanpa pengurutan terdaftar dengan sort dokumen kosong.
Untuk menghapus filter, gunakan planCacheClearFilters perintah.
db.runCommand({ planCacheClearFilters: <collection>, query: <query pattern>, // optional sort: <sort specification>, // optional comment: <any> // optional })
Untuk menghapus setiap filter pada koleksi, hilangkan keduanya query dan: sort
db.runCommand({planCacheClearFilters: "foo"})
Menye query diakan sort keduanya dan menghapus hanya filter yang memiliki jenis yang tepat. Nilai-nilai di dalam query dinormalisasi, sehingga nilai representatif apa pun berfungsi. Untuk menghapus hanya filter yang disetel tanpa pengurutan, berikan sort dokumen kosong:
db.runCommand({planCacheClearFilters: "foo", query: {a: 1}, sort: {a: 1}}) db.runCommand({planCacheClearFilters: "foo", query: {a: 1}, sort: {}})
Memverifikasi bahwa filter diterapkan
explainOutput mencakup dua bidang yang melaporkan status filter cache rencana:
indexFilterSetadalahtrueketika filter ada pada koleksi untuk bentuk kueri.indexFilterAppliedtruehanya ketika kueri direncanakan menggunakan indeks dari daftar filter itu.
Dimulai dengan Amazon DocumentDB 5.0.2 dan 8.0.2, bidang ini dilaporkan untuk setiap perintah yang mendukung filter cache rencana, dan dalam output profiler untuk perintah tersebut. Dalam versi minor sebelumnya mereka dilaporkan hanya untuk find perintah. Untuk informasi lebih lanjut tentang membaca penjelasan keluaran, lihatAnalisis rencana kueri.
Filter dapat mencocokkan bentuk kueri tanpa diterapkan. Jika tidak ada indeks dalam daftar filter yang dapat melayani kueri, perencana merencanakan ulang tanpa filter dan memilih indeks biaya. Dalam hal ini indexFilterSet adalah true dan indexFilterApplied sedangfalse. Ini terjadi ketika indeks bernama tidak mencakup bidang kueri, ketika indeks bernama tidak ada, atau ketika $regex bentuk tidak dapat menghasilkan batas indeks, seperti pola yang tidak tertanam atau tidak peka huruf besar-kecil.
Contoh
Contoh berikut menggunakan orders koleksi, dan customers koleksi untuk $lookup contoh, dengan indeks ini:
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
Contoh: menyematkan ku eri pencarian ke indeks majemuk
Pertimbangkan kueri yang memfilter status dan mengurutkanorderDate:
db.orders.find({ status: "SHIPPED" }).sort({ orderDate: 1 })
Indeks maj status_1_orderDate_1 emuk memenuhi predikat dan sortir, jadi tidak diperlukan pengurutan terpisah. Jika perencana memilihstatus_1, kueri harus mengurutkan hasilnya, yang menambahkan SORT tahap dan menjadi lebih mahal seiring bertambahnya jumlah pesanan yang cocok. Untuk membatasi perencana ke indeks majemuk untuk bentuk ini:
db.runCommand({planCacheSetFilter: "orders", query: { status: "SHIPPED" }, sort: { orderDate: 1 }, indexes: [ "status_1_orderDate_1" ]})
Karena nilai dinormalisasi keluar dari bentuk, filter yang satu ini juga mencakup { status: "PENDING" }{ status: "CANCELLED" },, dan setiap nilai lainnya status dengan jenis yang sama. Itu tidak mencakup predikat yang sama dengan jenis yang berbeda, atau tanpa jenis, yang merupakan bentuk terpisah. Konfirmasikan filter mulai berlaku denganexplain:
db.orders.find({ status: "SHIPPED" }).sort({ orderDate: 1 }).explain()
Laporan keluaran indexFilterSet: true danindexFilterApplied: true, dan nama IXSCAN panggungstatus_1_orderDate_1.
Contoh: menyematkan pembaruan ke indeks selektif
Pembaruan harus menemukan dokumen untuk dimodifikasi sebelum dapat menulisnya, dan pencarian itu menggunakan indeks dengan cara yang sama seperti pembacaan. Ketika predikat dapat dilayani oleh lebih dari satu indeks, indeks yang dipilih perencana menentukan berapa banyak dokumen yang diperiksa pembaruan.
db.orders.updateMany( { customerId: 4815, status: "PENDING" }, { $set: { status: "CANCELLED" } } )
Kedu customerId_1 anya dan status_1 dapat melayani predikat ini. Untuk menyematkan pembaruan kecustomerId_1:
db.runCommand({planCacheSetFilter: "orders", query: { customerId: 4815, status: "PENDING" }, indexes: [ "customerId_1" ]})
Filter pada perintah tulis memerlukan Amazon DocumentDB 5.0.2 atau 8.0.2 dan Planner versi 2.0 atau yang lebih baru. Veri explain fikasi dengan pembaruan:
db.runCommand({explain: {update: "orders", updates: [{ q: { customerId: 4815, status: "PENDING" }, u: { $set: { status: "CANCELLED" } }, multi: true }]}})
Rencana kemenangan adalah UPDATE tahap demi IXSCAN satucustomerId_1. Filter yang sama berlaku untuk delete dan findAndModify perintah yang menggunakan bentuk kueri ini, karena bentuknya tidak menyertakan jenis penulisan.
Contoh: menyematkan pipeline agregat dan koleksi asing $lookup
Untuk agregasi, bentuknya diambil dari $match tahap terdepan dan $sort segera setelahnya. Tahapan di luar itu$project, seperti $group atau, bukan bagian dari bentuk.
db.orders.aggregate([ { $match: { status: "SHIPPED" } }, { $group: { _id: "$customerId", total: { $sum: "$amount" } } } ])
Filter yang ditetapkan pada $match predikat mendorong indeks yang digunakan untuk membaca: orders
db.runCommand({planCacheSetFilter: "orders", query: { status: "SHIPPED" }, indexes: [ "status_1" ]})
Filter juga berlaku untuk koleksi yang bergabung dengan $lookup ta $graphLookup hapan atau. Filter diatur pada koleksi asing, bukan pada koleksi yang dituju pipa. Dalam pipa berikut, orders adalah koleksi luar dan customers merupakan koleksi asing:
db.orders.aggregate([ { $lookup: { from: "customers", localField: "customerId", foreignField: "customerId", as: "customer" } } ])
Gabungan menyeli customers diki sekali per dokumen luar, sehingga indeks yang dipilih di sana diterapkan berulang kali dan biayanya dikalikan di seluruh pipa. Untuk menyematkan pemindaian itu ke indeks tertentu, atur filter customers untuk bentuk kesetaraan kunci gabungan:
db.runCommand({planCacheSetFilter: "customers", query: { customerId: 1 }, indexes: [ "customerId_1" ]})
Karena nilai dinormalisasi keluar dari bentuk, nilai di 1 atas adalah placeholder dan nilai apa pun menghasilkan filter yang sama. Ketika filter koleksi asing diterapkan, laporan tingkat atas dan indexFilterApplied bidangtrue, indexFilterSet dan indeks yang dipilih filter muncul di sisi asing dari rencana pemenang. Filter pada aggregate memerlukan Amazon DocumentDB 8.0.2 dan Planner versi 3.0.
Perilaku dengan petunjuk dan perubahan indeks
Filter cache paket lebih diutamakan daripada a
hint. Amazon DocumentDB menerapkan filter terlebih dahulu dan kemudian menerapkan petunjuk dalam daftar indeks yang diizinkan filter. Jika petunjuk menyebutkan indeks yang diizinkan filter, indeks itu digunakan. Jika petunjuk menyebutkan indeks yang tidak diizinkan oleh filter, petunjuk diabaikan dan perencana memilih di antara indeks biaya yang diizinkan. Kedua bentuk petunjuk berperilaku dengan cara yang sama, apakah Anda memberi nama indeks atau memberikan pola kuncinya.Misalnya, jika koleksi
foomemiliki indeksa_1,, danb_1a_1_b_1, dan Anda menetapkan filter pada bentuk{query: {a: {$eq: "@"}, b: {$eq: "@"}}, sort: {a: 1}}dengan daftar indeks["a_1", "a_1_b_1"], maka menjalankandb.foo.find({ a: 10, b: 20 }).sort({a: 1}).hint({ a: 1 })menggunakana_1, karena diberi nama dalam petunjuk dan diizinkan oleh filter.Menjatuhkan indeks tidak mengubah filter. Filter menyimpan nama indeks. Sementara indeks itu hilang, perencanaan melewatkannya. Jika indeks lain dalam daftar filter dapat melayani kueri, filter masih berlaku. Hanya ketika tidak ada indeks bernama yang tersedia,
indexFilterAppliedlapfalseorannya. Membuat ulang indeks dengan nama yang sama membuatnya memenuhi syarat lagi.Menghapus koleksi akan menghapus semua filter koleksi tersebut.