View a markdown version of this page

Perencana kueri v2 - Amazon DocumentDB

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Perencana kueri v2

Perencana kueri baru untuk Amazon DocumentDB (perencana versi 2.0) menampilkan kemampuan pengoptimalan kueri tingkat lanjut dan peningkatan kinerja. Planner versi 2.0 untuk Amazon DocumentDB 5.0 memberikan peningkatan kinerja hingga 10x dibandingkan versi sebelumnya saat menggunakan find dan update operator dengan indeks. Peningkatan kinerja terutama berasal dari penggunaan rencana indeks yang lebih optimal dan mengaktifkan dukungan pemindaian indeks untuk operator seperti operator negasi ($neq,$nin) dan bersarang. $elementMatch Kueri Planner versi 2.0 berjalan lebih cepat melalui teknik estimasi biaya yang lebih baik, algoritma yang dioptimalkan, dan stabilitas yang ditingkatkan. Planner versi 2.0 juga mendukung API filter cache rencana, yang meningkatkan stabilitas perencana. Dengan fitur ini, Amazon DocumentDB 5.0 sekarang menawarkan kemampuan untuk memilih dari berbagai versi perencana kueri.

Prasyarat

Prasyarat berikut berlaku untuk perencana versi 2.0:

  • Planner versi 2.0 tersedia di semua Wilayah AWS tempat mesin versi 5.0 tersedia.

  • Untuk memilih menggunakan versi 2.0 sebagai perencana kueri default, cluster Anda harus menggunakan patch engine versi 3.0.15902 atau yang lebih baru dari Amazon DocumentDB versi 5.0. Untuk langkah-langkah memperbarui ke patch versi engine terbaru, lihatMelakukan pembaruan patch ke versi mesin cluster.

  • Untuk menetapkan perencana versi 2.0 sebagai perencana kueri default, Anda memerlukan izin IAM untuk memperbarui grup parameter cluster.

  • Untuk Amazon DocumentDB 8.0, Planner versi 3.0 adalah perencana kueri default. Lihat Perencana kueri v3 untuk detail.

Memilih perencana versi 2.0 sebagai perencana kueri default

Gunakan langkah-langkah berikut untuk memilih 2.0 sebagai perencana kueri default dari konsol atau CLI:

  • Ikuti langkah-langkah Memodifikasi parameter cluster Amazon DocumentDB untuk memodifikasi grup parameter cluster Anda.

  • Untuk parameter berjudul 'PlannerVersion', ubah nilainya menjadi 2.0 yang menunjukkan perencana versi 2.0.

  • Pilih Terapkan segera (memilih Ter apkan saat reboot akan membuat pilihan tidak efektif sampai reboot cluster berikutnya).

Praktik terbaik

Untuk hasil yang diharapkan, gunakan praktik terbaik berikut saat menerapkan perencana versi 2.0:

  • Dalam cluster global, pilih plannerVersion nilai yang sama (1.0 atau 2.0) di grup parameter cluster untuk kedua Wilayah. Perhatikan bahwa memilih versi perencana yang berbeda di Wilayah primer dan sekunder dapat menyebabkan perilaku dan kinerja kueri yang tidak konsisten.

  • Memperbarui ke perencana versi 2.0 selama jendela pemeliharaan terjadwal atau selama periode lalu lintas berkurang akan menjadi yang paling tidak mengganggu, karena mungkin ada peningkatan tingkat kesalahan jika versi perencana diubah saat beban kerja aktif berjalan.

  • Planner versi 2.0 bekerja paling optimal dengan shell MongoDB versi 5.0.

Batasan

Batasan berikut berlaku untuk Planner versi 2.0:

  • Planner versi 2.0 tidak didukung di cluster elastis, yang akan kembali ke Planner versi 1.0.

  • Planner versi 2.0 tidak didukung untuk agregasi dan perintah berbeda, yang akan kembali ke Planner versi 1.0.

  • Beberapa bentuk kueri tidak dapat memiliki filter cache rencana yang ditetapkan pada mereka. Untuk daftar saat ini, lihatBentuk kueri yang didukung.

Perbaikan untuk Cari dan Memper barui Operator

Planner versi 2.0 mengoptimalkan operasi dasar termasukfind,update,delete, dan find-and-modify perintah. Bagian tab berikut menunjukkan kemampuan yang disempurnakan untuk indeks, serta peningkatan kinerja kueri dengan Planner versi 2.0:

Enhanced index support
  • Planner versi 2.0 menambahkan dukungan indeks untuk operator negasi termasuk $nin$ne,$not {eq},, dan$not {in}, serta $type dan$elemMatch.

    Sample Document: { "x": 10, "y": [1, 2, 3] } db.foo.createIndex({ "x": 1, "y": 1 }) db.foo.find({ "x": {$nin: [20, 30] }}) db.foo.find({"x":{ $type: "string" }}) db.foo.createIndex({"x.y": 1}) db.foo.find({"x":{$elemMatch:{"y":{$elemMatch:{"$gt": 3 }}}}})
  • Planner versi 2.0 menggunakan indeks jarang atau sebagian bahkan ketika tidak $exists ada dalam ekspresi kueri.

    Sample Document: {"name": "Bob", "email": "example@fake.com" } Using Planner Version 1.0, you can specify the command as shown below: db.foo.find({email: "example@fake.com", email: {$exists: true}}) Using Planner Version 2.0, you can specify command without $exists: db.foo.find({ email: "example@fake.com" })
  • Planner versi 2.0 akan menggunakan indeks parSIAL bahkan ketika kondisi kueri tidak persis sama dengan ekspresi filter indeks parSIAL.

    Sample Document: {"name": "Bob", "age": 34} db.foo.createIndex({"age":1},{partialFilterExpression:{"age":{$lt:50}}}) With Planner Version 1.0, index is used only when the query condition meets the partial index filter criterion: db.foo.find({"age":{$lt:50}}) With Planner Version 2.0, index is used even when the query condition doesn’t meet the index criterion: db.foo.find({"age":{$lt:30}})
  • Planner versi 2.0 menggunakan pemindaian indeks parSIAL dengan kueri $ElemMatch.

    Sample Document: {"name": "Bob", "age": [34,35,36]} db.foo.createIndex({"age":1},{partialFilterExpression:{"age":{$lt:50,$gt:20}}}) db.foo.find({age:{$elemMatch:{$lt:50,$gt:20}}})
  • Planner versi 2.0 menyertakan dukungan pemindaian indeks untuk$regex, tanpa perlu memberikan $hint kode aplikasi Anda. $regexmendukung indeks pada pencarian awalan saja.

    Sample Document: { "x": [1, 2, 3], "y": "apple" } db.foo.createIndex({ "x": 1, "y": 1 }) db.foo.find({"y":{ $regex: "^a" }})
  • Planner versi 2.0 meningkatkan kinerja kueri yang melibatkan indeks multi-kunci, dengan kondisi kesetaraan pada bidang multi-kunci.

    Sample Document: {"x": [1, 2, 3], "y": 5} db.foo.createIndex({"x": 1, "y":1}) db.foo.find({"x": 2, "y": {$gt: 1}}).limit(1)
  • Planner versi 2.0 meningkatkan kinerja kueri yang melibatkan beberapa filter, terutama pada koleksi dengan dokumen lebih besar dari 8 KB.

    Sample Document: {"x": 2, "y": 4, "z": 9, "t": 99} db.foo.find({$and: [{"x": {$gt : 1}, "y": {$gt : 3}, "z": {$lt : 10}, "t":{$lt : 100}}]})
  • Planner versi 2.0 meningkatkan kinerja kueri saat menggunakan $in operator dengan indeks majemuk dengan menghilangkan tahap pengurutan.

    Sample Document: {"x": 2, "y": 4, "z": 9, "t": 99} db.foo.createIndex({"x":1, "y":1}) db.foo.find({"x":2, "y":$in:[1,2,3,4]}).sort({x:1,y:1})

    Ini juga meningkatkan kinerja kueri yang menggunakan indeks multi-kunci dengan $in elemen.

    Sample Document: {"x": [1, 2, 3]} db.foo.createIndex({"x": 1}) db.foo.find("x":{$in:[>100 elements]})
Query performance improvements
  • Planner versi 2.0 meningkatkan kinerja kueri yang melibatkan beberapa filter, terutama pada koleksi dengan dokumen lebih besar dari 8 KB.

    Sample Document: {"x": 2, "y": 4, "z": 9, "t": 99} db.foo.find({$and: [{"x": {$gt : 1}, "y": {$gt : 3}, "z": {$lt : 10}, "t":{$lt : 100}}]})
  • Planner versi 2.0 meningkatkan kinerja kueri saat menggunakan $in operator dengan indeks majemuk dengan menghilangkan tahap pengurutan.

    Sample Document: {"x": 2, "y": 4, "z": 9, "t": 99} db.foo.createIndex({"x":1, "y":1}) db.foo.find({"x":2, "y":$in:[1,2,3,4]}).sort({x:1,y:1})

    Ini juga meningkatkan kinerja kueri yang menggunakan indeks multikey dengan $in elemen.

    Sample Document: {"x": [1, 2, 3]} db.foo.createIndex({"x": 1}) db.foo.find("x":{$in:[>100 elements]})

Rencanakan filter cache

Planner versi 2.0 menambahkan dukungan untuk filter cache rencana, juga disebut filter indeks, yang memungkinkan Anda membatasi kumpulan indeks yang dipertimbangkan perencana untuk bentuk kueri tertentu. Filter diatur dengan perintah database dan diterapkan pada server, jadi jika Anda mengalami regresi kueri, Anda dapat menguranginya tanpa memodifikasi kode aplikasi Anda.

Pada perencana versi 2.0, filter cache rencana berlaku untuk count perintah find dan, dan dimulai dengan Amazon DocumentDB 5.0.2 dan 8.0.2 juga untuk perintahupdate,delete, dan. findAndModify Per distinct aggregate intah dan memerlukan perencana versi 3.0.

Untuk informasi selengkapnya tentang referensi perintah, bentuk kueri yang didukung, contoh kerja, dan bagaimana filter berinteraksi dengan petunjuk, lihatRencanakan filter cache.

Perbedaan perilaku potensial antara perencana versi 1.0, 2.0, dan MongoDB

Dalam beberapa kasus edge, ada kemungkinan bahwa Planner versi 2.0 dapat menghasilkan hasil yang sedikit berbeda dari hasil di MongoDB. Bagian ini membahas beberapa contoh kemungkinan ini.

$(update) and $(projection)
  • Dalam beberapa kasus, $(update) dan $(projection) operator di MongoDB mungkin berperilaku berbeda dari perencana Amazon DocumentDB versi 1.0. Di bawah ini adalah beberapa contoh:

    db.students_list.insertMany( [ { _id: 5, student_ids: [ 100, 200 ], grades: [ 95, 100 ], grad_year: [ 2024, 2023 ] } ] )
    db.students_list.updateOne({ student_ids: 100, grades: 100, grad_year: 2024 }, { $set: { “grad_year.$”: 2025 } }
    • Planner versi 1.0 — Bidang pembaruan 2022

    • MongoDB — Bidang pembaruan 2022

    • Planner versi 2.0 — Bidang pembaruan 2021

  • db.col.insert({x:[1,2,3]}) db.col.update({$and:[{x:1},{x:3}]},{$set:{"x.$":500}})
    • Planner versi 1.0 - Secara acak memperbarui elemen pertama yang cocok

    • MongoDB - Secara acak memperbarui elemen pertama yang cocok

    • Planner versi 2.0 - Tidak membuat pembaruan

  • db.col.insert({x:[1,2,3]}) db.col.find()
    • Planner versi 1.0 - Secara acak memilih elemen yang cocok

    • MongoDB - Secara acak memilih elemen yang cocok

    • Planner versi 2.0 - Tidak membuat pilihan

  • db.col.insert({x:100}) db.col.update({x:100},{x:100})
    • Planner versi 1.0 - nPerubahan jumlah yang dimodifikasi

    • MongoDB — nPerubahan jumlah yang dimodifikasi

    • Planner versi 2.0 — Jumlah nModified tidak berubah saat diperbarui dengan nilai yang sama.

  • Saat $(update) operator digunakan dengan$setOnInsert, planner versi 1.0 dan MongoDB menimbulkan kesalahan, tetapi planner versi 2.0 tidak.

  • Mengganti nama bidang yang tidak ada untuk menimbulkan $field kesalahan di perencana versi 2.0, sedangkan tidak menghasilkan pembaruan di perencana versi 1.0 dan MongoDB.

Index behavior
  • Planner versi 2.0 menimbulkan kesalahan saat $hint diterapkan dengan indeks yang tidak sesuai, sedangkan planner versi 1.0 dan MongoDB tidak.

    // Insert db.col.insert({x:1}) db.col.insert({x:2}) db.col.insert({x:3}) // Create index on x with partialFilter Expression {x:{$gt:2}} db.col.createIndex({x:1},{partialFilterExpression:{x:{$gt:2}}}) // Mongodb allows hint on the following queries db.col.find({x:1}).hint("x_1") // result is no documents returned because {x:1} is not indexed by the partial index // Without $hint mongo should return {x:1}, thus the difference in result between COLSCAN and IXSCAN DocumentDB will error out when $hint is applied on such cases. db.col.find({x:1}).hint("x_1") Error: error: { "ok" : 0, "operationTime" : Timestamp(1746473021, 1), "code" : 2, "errmsg" : "Cannot use Hint for this Query. Index is multi key index , partial index or sparse index and query is not optimized to use this index." } rs0:PRIMARY> db.runCommand({"planCacheSetFilter": "col", "query": { location: {$nearSphere: {$geometry: {type: "Point", coordinates: [1, 1]}}}}, "indexes": ["name_1"]}) { "ok" : 0, "operationTime" : Timestamp(1750815778, 1), "code" : 303, "errmsg" : "Unsupported query shape for index filter $nearSphere" }
  • $neartidak dapat digunakan $hint({“$natural”:1}) dalam Planner versi 2.0.

    // indexes present are index on x and geo index rs0:PRIMARY> db.usarestaurants.getIndexes() [ { "v" : 4, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.usarestaurants" }, { "v" : 4, "key" : { "location" : "2dsphere" }, "name" : "location_2dsphere", "ns" : "test.usarestaurants", "2dsphereIndexVersion" : 1 } ] // Planner Version 2.0 will throw an error when $hint is applied with index "x_1" rs0:PRIMARY> db.usarestaurants.find({ "location":{ "$nearSphere":{ "$geometry":{ "type":"Point", "coordinates":[ -122.3516, 47.6156 ] }, "$minDistance":1, "$maxDistance":2000 } } }, { "name":1 }).hint({"$natural": 1}) Error: error: { "ok" : 0, "operationTime" : Timestamp(1746475524, 1), "code" : 291, "errmsg" : "unable to find index for $geoNear query" } // Planner Version 1.0 and MongoDB will not throw an error db.usarestaurants.find({ "location":{ "$nearSphere":{ "$geometry":{ "type":"Point", "coordinates":[ -122.3516, 47.6156 ] }, "$minDistance":1, "$maxDistance":2000 } } }, { "name":1 }).hint({"$natural": 1}) { "_id" : ObjectId("681918e087dadfd99b7f0172"), "name" : "Noodle House" }
  • Sementara MongoDB mendukung pemindaian indeks regex lengkap, Planner versi 2.0 mendukung pemindaian indeks regex hanya pada bidang awalan.

    // index on x db.col.createIndex({x:1}) // index scan is used only for prefix regexes rs0:PRIMARY> db.col.find({x: /^x/}).explain() { "queryPlanner" : { "plannerVersion" : 2, "namespace" : "test.col", "winningPlan" : { "stage" : "IXSCAN", "indexName" : "x_1", "direction" : "forward", "indexCond" : { "$and" : [ { "x" : { "$regex" : /^x/ } } ] }, "filter" : { "x" : { "$regex" : /^x/ } } } }, "indexFilterSet" : false, "indexFilterApplied" : false, "ok" : 1, "operationTime" : Timestamp(1746474527, 1) } // COLSCAN is used for non-prefix regexes rs0:PRIMARY> db.col.find({x: /x$/}).explain() { "queryPlanner" : { "plannerVersion" : 2, "namespace" : "test.col", "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "x" : { "$regex" : /x$/ } } } }, "indexFilterSet" : false, "indexFilterApplied" : false, "ok" : 1, "operationTime" : Timestamp(1746474575, 1)
  • Ada beberapa perbedaan yang melekat dalam menggunakan filter cache rencana dengan Planner versi 2.0 dibandingkan dengan MongoDB. Sementara perencana versi 2.0 tidak mendukung penentuan “proyeksi” dan “kolasi” dengan filter cache rencana, MongoDB melakukannya. Namun, filter indeks MongoDB hanya dalam memori dan hilang setelah restart. Planner versi 2.0 mempertahankan filter indeks melalui restart dan patch.

Others
  • Format log audit DML saat menggunakan Planner versi 2.0 sedikit berbeda dari Planner versi 1.0.

    command - db.col.find({x:1}) ************** Audit logs generated ****************** // v1 format for dml audit logs {"atype":"authCheck","ts":1746473479983,"timestamp_utc":"2025-05-05 19:31:19.983","remote_ip":"127.0.0.1:47022","users":[{"user":"serviceadmin","db":"test"}],"param":{"command":"find","ns":"test.col","args":{"batchSize":101,"filter":{"x":1},"find":"col","limit":18446744073709551615,"lsid":{"id":{"$binary":"P6RCGz9ZS4iWBSSHWXW15A==","$type":"4"},"uid":{"$binary":"6Jo8PisnEi3dte03+pJFjdCyn/5cGQL8V2KqaoWsnk8=","$type":"0"}},"maxScan":18446744073709551615,"singleBatch":false,"skip":0,"startTransaction":false},"result":0}} // v2 formal for dml audit logs {"atype":"authCheck","ts":1746473583711,"timestamp_utc":"2025-05-05 19:33:03.711","remote_ip":"127.0.0.1:37754","users":[{"user":"serviceadmin","db":"test"}],"param":{"command":"find","ns":"test.col","args":{"find":"col","filter":{"x":1},"lsid":{"id":{"$binary":"nJ88TGCSSd+BeD2+ZtrhQg==","$type":"4"}},"$db":"test"},"result":0}}
  • Kondisi indeks sebagai bagian dari rencana penjelasan:

    rs0:PRIMARY> db.col.createIndex({index1:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1, "operationTime" : Timestamp(1761149251, 1) }

    Planner versi 2.0 menjelaskan keluaran rencana yang menampilkan kondisi indeks dan filter:

    rs0:PRIMARY> db.col.find({$and:[{price:{$eq:300}},{item:{$eq:"apples"}}]}).explain() { "queryPlanner" : { "plannerVersion" : 2, "namespace" : "test.col", "winningPlan" : { "stage" : "IXSCAN", "indexName" : "price_1", "direction" : "forward", "indexCond" : { "$and" : [ { "price" : { "$eq" : 300 } } ] }, "filter" : { "$and" : [ { "item" : { "$eq" : "apples" } } ] } } }, "indexFilterSet" : false, "indexFilterApplied" : false, "ok" : 1, "operationTime" : Timestamp(1761149497, 1) }

    Planner versi 1.0 menjelaskan keluaran rencana:

    rs0:PRIMARY> db.col.find({$and:[{price:{$eq:300}},{item:{$eq:"apples"}}]}).explain() { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.col", "winningPlan" : { "stage" : "IXSCAN", "indexName" : "price_1", "direction" : "forward" } }, "ok" : 1, "operationTime" : Timestamp(1761149533, 1) }

Planner versi 2.0 menjembatani kesenjangan perilaku dengan MongoDB

Ada beberapa area di mana perencana versi 2.0 menutup kesenjangan perilaku dari MongoDB:

  • Planner versi 2.0 memungkinkan pencarian indeks numerik pada array pipih untuk: $elemMatch

    doc: {"x" : [ [ { "y" : 1 } ] ] } // Planner Version 2 and mongo > db.bar.find({"x.0": {$elemMatch: {y: 1}}}) { "_id" : ObjectId("68192947945e5846634c455a"), "x" : [ [ { "y" : 1 } ] ] } > db.bar.find({"x": {$elemMatch: {"0.y": 1}}}) { "_id" : ObjectId("68192947945e5846634c455a"), "x" : [ [ { "y" : 1 } ] ] } //Whereas Planner Version 1 wouldn't return any results. > db.bar.find({"x.0": {$elemMatch: {y: 1}}}) > db.bar.find({"x": {$elemMatch: {"0.y": 1}}})
  • Sementara perencana versi 1.0 mengecualikan string dalam proyeksi, perilaku perencana versi 2.0 selaras dengan MongoDB dan memperlakukannya sebagai nilai literal”

    // Planner V2/ MongoDB > db.col.find() { "_id" : ObjectId("681537738aa101903ed2fe05"), "x" : 1, "y" : 1 } > db.col.find({},{x:"string"}) { "_id" : ObjectId("681537738aa101903ed2fe05"), "x" : "string" } // Planner V1 treats strings as exclude in projection rs0:PRIMARY> db.col.find() { "_id" : ObjectId("68153744d42969f11d5cca72"), "x" : 1, "y" : 1 } rs0:PRIMARY> db.col.find({},{x:"string"}) { "_id" : ObjectId("68153744d42969f11d5cca72"), "y" : 1 }
  • Planner versi 2.0, seperti MongoDB, tidak mengizinkan proyeksi pada bidang yang sama “x” dan “x.a”:

    // Planner version 2/MongoDB will error out > db.col.find() { "_id" : ObjectId("68153da2012265816bc9ba23"), "x" : [ { "a" : 1 }, 3 ] } db.col.find({},{"x.a":1,"x":1}) // error // Planner Version 1 does not error out db.col.find() { "_id" : ObjectId("68153da2012265816bc9ba23"), "x" : [ { "a" : 1 }, 3 ] } db.col.find({},{"x.a":1,"x":1}) { "_id" : ObjectId("68153d60143af947c720d099"), "x" : [ { "a" : 1 }, 3 ] }
  • Planner versi 2.0, seperti MongoDB, memungkinkan proyeksi pada subdokumen:

    // Planner Version2/MongoDB supports projections on subdocuments db.col.find() { "_id" : ObjectId("681542d8f35ace71f0a50004"), "x" : [ { "y" : 100 } ] } > db.col.find({},{"x":{"y":1}}) { "_id" : ObjectId("681542b7a22d548e4ac9ddea"), "x" : [ { "y" : 100 } ] } // Planner V1 throws error if projection is subdocument db.col.find() { "_id" : ObjectId("681542d8f35ace71f0a50004"), "x" : [ { "y" : 100 } ] } rs0:PRIMARY> db.col.find({},{"x":{"y":1}}) Error: error: { "ok" : 0, "operationTime" : Timestamp(1746223914, 1), "code" : 2, "errmsg" : "Unknown projection operator y" }
  • Dengan Planner versi 2.0, seperti MongoDB, proyeksi tidak mendukung bidang setelah operator: $

    // Mongo and Planner Version 2 will error out db.col.find() { "_id" : ObjectId("68155fa812f843439b593f3f"), "x" : [ { "a" : 100 } ] } db.col.find({"x.a":100},{"x.$.a":1}) - // error // v1 will not error out db.col.find() { "_id" : ObjectId("68155fa812f843439b593f3f"), "x" : [ { "a" : 100 } ] } db.col.find({"x.a":100},{"x.$.a":1}) { "_id" : ObjectId("68155dee13b051d58239cd0a"), "x" : [ { "a" : 100 } ] }
  • Planner versi 2.0, seperti MongoDB, memungkinkan penggunaan: $hint

    // v1 will error out on $hint if there are no filters db.col.find({}).hint("x_1") Error: error: { "ok" : 0, "operationTime" : Timestamp(1746466616, 1), "code" : 2, "errmsg" : "Cannot use Hint for this Query. Index is multi key index , partial index or sparse index and query is not optimized to use this index." } // Mongo and Planner Version 2 will allow $hint usage db.col.find({}).hint("x_1") { "_id" : ObjectId("6818f790d5ba9359d68169cf"), "x" : 1 }