Azure Cosmos DB for MongoDB kullanırken karşılaşılan sorgu sorunlarını giderin
ŞUNLAR IÇIN GEÇERLIDIR: MongoDB
Bu makalede, Azure Cosmos DB'de sorgu sorunlarını gidermek için önerilen genel bir yaklaşım açıklanmaktadır. Bu makalede açıklanan adımları olası sorgu sorunlarına karşı eksiksiz bir savunma olarak değerlendirmemeniz gerekir ancak en yaygın performans ipuçlarını buraya dahil ettik. MongoDB için Azure Cosmos DB API'sinde yavaş veya pahalı sorguların sorunlarını gidermek için bu makaleyi başlangıç noktası olarak kullanmalısınız. NoSQL için Azure Cosmos DB kullanıyorsanız NoSQL için API sorgu sorun giderme kılavuzu makalesine bakın.
Azure Cosmos DB'deki sorgu iyileştirmeleri aşağıda gösterildiği gibi geniş bir kategoriye ayrılır:
- Sorgunun İstek Birimi (RU) ücretini azaltan iyileştirmeler
- Yalnızca gecikme süresini azaltan iyileştirmeler
Sorgunun RU ücretini azaltırsanız genellikle gecikme süresini de azaltırsınız.
Bu makalede, beslenme veri kümesini kullanarak yeniden oluşturabileceğiniz örnekler sağlanmaktadır.
Not
Bu makalede, Azure Cosmos DB'nin 3.6 ve üzeri sürüme sahip MongoDB hesapları için API'sini kullandığınız varsayılır. Sürüm 3.2'de kötü performans gösteren bazı sorguların 3.6+ sürümlerinde önemli geliştirmeler vardır. Destek isteği göndererek sürüm 3.6'ya yükseltin.
Ölçümleri almak için $explain komutunu kullanma
Azure Cosmos DB'de bir sorguyu iyileştirdiğinizde ilk adım her zaman sorgunuzun RU ücretini almaktır. Kabaca bir kılavuz olarak, ücretleri 50 RU'dan fazla olan sorgular için RU ücretini düşürmenin yollarını araştırmalısınız.
RU ücretini almanın yanı sıra, sorgu ve dizin kullanım ölçümlerini almak için $explain
komutunu kullanmalısınız. Sorguyu çalıştıran ve sorgu ve dizin kullanım ölçümlerini göstermek için komutunu kullanan $explain
bir örnek aşağıda verilmiştir:
$explain komutu:
db.coll.find({foodGroup: "Baby Foods"}).explain({"executionStatistics": true })
Çıktı:
{
"stages" : [
{
"stage" : "$query",
"timeInclusiveMS" : 905.2888,
"timeExclusiveMS" : 905.2888,
"in" : 362,
"out" : 362,
"details" : {
"database" : "db-test",
"collection" : "collection-test",
"query" : {
"foodGroup" : {
"$eq" : "Baby Foods"
}
},
"pathsIndexed" : [],
"pathsNotIndexed" : [
"foodGroup"
],
"shardInformation" : [
{
"activityId" : "e68e6bdd-5e89-4ec5-b053-3dbbc2428140",
"shardKeyRangeId" : "0",
"durationMS" : 788.5867,
"preemptions" : 1,
"outputDocumentCount" : 362,
"retrievedDocumentCount" : 8618
}
],
"queryMetrics" : {
"retrievedDocumentCount" : 8618,
"retrievedDocumentSizeBytes" : 104963042,
"outputDocumentCount" : 362,
"outputDocumentSizeBytes" : 2553535,
"indexHitRatio" : 0.0016802042237178,
"totalQueryExecutionTimeMS" : 777.72,
"queryPreparationTimes" : {
"queryCompilationTimeMS" : 0.19,
"logicalPlanBuildTimeMS" : 0.14,
"physicalPlanBuildTimeMS" : 0.09,
"queryOptimizationTimeMS" : 0.03
},
"indexLookupTimeMS" : 0,
"documentLoadTimeMS" : 687.22,
"vmExecutionTimeMS" : 774.09,
"runtimeExecutionTimes" : {
"queryEngineExecutionTimeMS" : 37.45,
"systemFunctionExecutionTimeMS" : 10.82,
"userDefinedFunctionExecutionTimeMS" : 0
},
"documentWriteTimeMS" : 49.42
}
}
}
],
"estimatedDelayFromRateLimitingInMilliseconds" : 0.0,
"continuation" : {
"hasMore" : false
},
"ok" : 1.0
}
$explain
Komut çıktısı uzundur ve sorgu yürütme hakkında ayrıntılı bilgilere sahiptir. Ancak genel olarak, sorgu performansını iyileştirirken odaklanmanız gereken birkaç bölüm vardır:
Metrik Sistem | Açıklama |
---|---|
timeInclusiveMS |
Arka uç sorgusu gecikme süresi |
pathsIndexed |
Sorgunun kullandığı dizinleri gösterir |
pathsNotIndexed |
Varsa, sorgunun kullanabileceği dizinleri gösterir |
shardInformation |
Belirli bir fiziksel bölüm için sorgu performansının özeti |
retrievedDocumentCount |
Sorgu altyapısı tarafından yüklenen belge sayısı |
outputDocumentCount |
Sorgu sonuçlarında döndürülen belge sayısı |
estimatedDelayFromRateLimitingInMilliseconds |
Hız sınırlaması nedeniyle tahmini ek sorgu gecikme süresi |
Sorgu ölçümlerini aldıktan sonra sorgunuzun ile outputDocumentCount
karşılaştırınretrievedDocumentCount
. Bu makalede gözden geçirecek ilgili bölümleri belirlemek için bu karşılaştırmayı kullanın. retrievedDocumentCount
, sorgu altyapısının yüklemesi gereken belge sayısıdır. outputDocumentCount
, sorgunun sonuçları için gereken belge sayısıdır. retrievedDocumentCount
değeri değerinden outputDocumentCount
önemli ölçüde yüksekse, sorgunuzun dizin kullanamayan ve tarama yapması gereken en az bir bölümü vardır.
Senaryonuza yönelik ilgili sorgu iyileştirmelerini anlamak için aşağıdaki bölümlere bakın.
Sorguya ait RU ücreti çok yüksek
Alınan Belge Sayısı, Çıktı Belge Sayısından oldukça fazla
Alınan Belge Sayısı, Çıktı Belge Sayısı'na yaklaşık olarak eşittir
Sorguya ait RU ücreti kabul edilebilir ancak gecikme süresi yine de çok yüksek
Alınan belge sayısının çıkış belgesi sayısını aştığı sorgular
retrievedDocumentCount
, sorgu altyapısının yüklenmesi gereken belge sayısıdır. outputDocumentCount
, sorgu tarafından döndürülen belge sayısıdır. retrievedDocumentCount
değeri değerinden outputDocumentCount
önemli ölçüde yüksekse, sorgunuzun dizin kullanamayan ve tarama yapması gereken en az bir bölümü vardır.
Aşağıda, dizin tarafından tam olarak sunulmamış bir tarama sorgusu örneği verilmiştir:
$explain komutu:
db.coll.find(
{
$and : [
{ "foodGroup" : "Cereal Grains and Pasta"},
{ "description" : "Oat bran, cooked"}
]
}
).explain({"executionStatistics": true })
Çıktı:
{
"stages" : [
{
"stage" : "$query",
"timeInclusiveMS" : 436.5716,
"timeExclusiveMS" : 436.5716,
"in" : 1,
"out" : 1,
"details" : {
"database" : "db-test",
"collection" : "indexing-test",
"query" : {
"$and" : [
{
"foodGroup" : {
"$eq" : "Cereal Grains and Pasta"
}
},
{
"description" : {
"$eq" : "Oat bran, cooked"
}
}
]
},
"pathsIndexed" : [],
"pathsNotIndexed" : [
"foodGroup",
"description"
],
"shardInformation" : [
{
"activityId" : "13a5977e-a10a-4329-b68e-87e4f0081cac",
"shardKeyRangeId" : "0",
"durationMS" : 435.4867,
"preemptions" : 1,
"outputDocumentCount" : 1,
"retrievedDocumentCount" : 8618
}
],
"queryMetrics" : {
"retrievedDocumentCount" : 8618,
"retrievedDocumentSizeBytes" : 104963042,
"outputDocumentCount" : 1,
"outputDocumentSizeBytes" : 6064,
"indexHitRatio" : 0.0,
"totalQueryExecutionTimeMS" : 433.64,
"queryPreparationTimes" : {
"queryCompilationTimeMS" : 0.12,
"logicalPlanBuildTimeMS" : 0.09,
"physicalPlanBuildTimeMS" : 0.1,
"queryOptimizationTimeMS" : 0.02
},
"indexLookupTimeMS" : 0,
"documentLoadTimeMS" : 387.44,
"vmExecutionTimeMS" : 432.93,
"runtimeExecutionTimes" : {
"queryEngineExecutionTimeMS" : 45.36,
"systemFunctionExecutionTimeMS" : 16.86,
"userDefinedFunctionExecutionTimeMS" : 0
},
"documentWriteTimeMS" : 0.13
}
}
}
],
"estimatedDelayFromRateLimitingInMilliseconds" : 0.0,
"continuation" : {
"hasMore" : false
},
"ok" : 1.0
}
retrievedDocumentCount
(8618), (1) değerinden outputDocumentCount
önemli ölçüde daha yüksektir ve bu da bu sorgunun belge taraması gerektirdiğini gösterir.
Gerekli dizinleri ekle
Diziyi pathsNotIndexed
denetlemeli ve bu dizinleri eklemelisiniz. Bu örnekte ve yolları foodGroup
description
dizine alınmalıdır.
"pathsNotIndexed" : [
"foodGroup",
"description"
]
Azure Cosmos DB'nin MongoDB API'sindeki en iyi dizin oluşturma yöntemleri MongoDB'den farklıdır. MongoDB için Azure Cosmos DB API'sinde bileşik dizinler yalnızca birden çok özelliğe göre verimli bir şekilde sıralaması gereken sorgularda kullanılır. Birden çok özellik üzerinde filtre içeren sorgularınız varsa, bu özelliklerin her biri için tek alan dizinleri oluşturmanız gerekir. Sorgu önkoşulları birden çok tek alan dizini kullanabilir.
Joker karakter dizinleri dizin oluşturmayı basitleştirebilir. MongoDB'den farklı olarak, joker dizinler sorgu koşullarında birden çok alanı destekleyebilir. Her özellik için ayrı bir dizin oluşturmak yerine tek bir joker karakter dizini kullanırsanız sorgu performansında bir fark olmayacaktır. Tüm özellikler için joker karakter dizini eklemek, tüm sorgularınızı iyileştirmenin en kolay yoludur.
Yazma veya okuma kullanılabilirliğini etkilemeden istediğiniz zaman yeni dizinler ekleyebilirsiniz. Dizin dönüştürme ilerleme durumunu izleyebilirsiniz.
Hangi toplama işlemlerinin dizini kullandığını anlama
Çoğu durumda, MongoDB için Azure Cosmos DB API'sindeki toplama işlemleri kısmen dizinleri kullanır. Genellikle sorgu altyapısı önce eşitlik ve aralık filtreleri uygular ve dizinleri kullanır. Bu filtreleri uyguladıktan sonra sorgu altyapısı ek filtreleri değerlendirebilir ve gerekirse toplama işlemini hesaplamak için kalan belgeleri yüklemeye başvurabilir.
Bir örnek aşağıda verilmiştir:
db.coll.aggregate( [
{ $match: { foodGroup: 'Fruits and Fruit Juices' } },
{
$group: {
_id: "$foodGroup",
total: { $max: "$version" }
}
}
] )
Bu durumda dizinler aşamayı $match
iyileştirebilir. için foodGroup
dizin eklemek sorgu performansını önemli ölçüde artırır. MongoDB'de olduğu gibi dizin kullanımını en üst düzeye çıkarmak için toplama işlem hattının olabildiğince erken bir bölümüne yerleştirmelisiniz $match
.
Azure Cosmos DB'nin MongoDB API'sinde dizinler gerçek toplama için kullanılmaz ve bu durumda olur $max
. üzerinde version
dizin eklemek sorgu performansını iyileştirmez.
Alınan belge sayısının Çıktı Belge Sayısı'na eşit olduğu sorgular
retrievedDocumentCount
değeri yaklaşık olarak değerine outputDocumentCount
eşitse, sorgu altyapısının birçok gereksiz belgeyi taraması gerekmezdi.
Bölümler arası sorguları en aza indirme
Azure Cosmos DB, İstek Birimi ve veri depolama gereksinimleri arttıkça ayrı kapsayıcıları ölçeklendirmek için bölümleme kullanır. Her fiziksel bölümün ayrı ve bağımsız bir dizini vardır. Sorgunuzda kapsayıcınızın bölüm anahtarıyla eşleşen bir eşitlik filtresi varsa yalnızca ilgili bölümün dizinini denetlemeniz gerekir. Bu iyileştirme sorguya gereken toplam RU sayısını azaltır. Bölüm içi sorgular ile bölümler arası sorgular arasındaki farklar hakkında daha fazla bilgi edinin.
Çok sayıda sağlanan RU'nuz (30.000'den fazla) veya depolanan büyük miktarda veriniz (yaklaşık 100 GB'tan fazla) varsa, sorgu RU ücretlerinde önemli bir azalma görmek için büyük olasılıkla yeterince büyük bir kapsayıcınız vardır.
Her fiziksel bölümün shardInformation
sorgu ölçümlerini anlamak için diziyi de kontrol edebilirsiniz. Benzersiz shardKeyRangeId
değerlerin sayısı, sorgunun yürütülmesi gereken fiziksel bölüm sayısıdır. Bu örnekte sorgu dört fiziksel bölümde yürütüldü. Yürütmenin dizin kullanımından tamamen bağımsız olduğunu anlamak önemlidir. Başka bir deyişle, bölümler arası sorgular dizinleri kullanmaya devam edebilir.
"shardInformation" : [
{
"activityId" : "42f670a8-a201-4c58-8023-363ac18d9e18",
"shardKeyRangeId" : "5",
"durationMS" : 24.3859,
"preemptions" : 1,
"outputDocumentCount" : 463,
"retrievedDocumentCount" : 463
},
{
"activityId" : "a8bf762a-37b9-4c07-8ed4-ae49961373c0",
"shardKeyRangeId" : "2",
"durationMS" : 35.8328,
"preemptions" : 1,
"outputDocumentCount" : 905,
"retrievedDocumentCount" : 905
},
{
"activityId" : "3754e36b-4258-49a6-8d4d-010555628395",
"shardKeyRangeId" : "1",
"durationMS" : 67.3969,
"preemptions" : 1,
"outputDocumentCount" : 1479,
"retrievedDocumentCount" : 1479
},
{
"activityId" : "a69a44ee-db97-4fe9-b489-3791f3d52878",
"shardKeyRangeId" : "0",
"durationMS" : 185.1523,
"preemptions" : 1,
"outputDocumentCount" : 867,
"retrievedDocumentCount" : 867
}
]
Sorgu gecikme süresini azaltan iyileştirmeler
Çoğu durumda, sorgu gecikmesi hala çok yüksek olduğunda RU ücreti kabul edilebilir. Aşağıdaki bölümlerde, sorgu gecikme süresini azaltmaya yönelik ipuçlarına genel bir bakış verilmiştir. Aynı sorguyu aynı veri kümesinde birden çok kez çalıştırırsanız, genellikle her seferinde aynı RU ücretine sahip olacaktır. Ancak sorgu gecikme süresi, sorgu yürütmeleri arasında farklılık gösterebilir.
Yakınlığı geliştirme
Azure Cosmos DB hesabından farklı bir bölgeden çalıştırılan sorgular, aynı bölgede çalıştırıldığından daha yüksek gecikme süresine sahip olur. Örneğin, masaüstü bilgisayarınızda kod çalıştırıyorsanız, gecikmenin, sorgunun Azure Cosmos DB ile aynı Azure bölgesindeki bir sanal makineden gelmesine kıyasla onlarca veya yüzlerce milisaniye daha yüksek (veya daha fazla) olmasını beklemelisiniz. Verilerinizi uygulamanıza yaklaştırabilmeniz için Azure Cosmos DB'de verileri genel olarak dağıtmak kolaydır.
Sağlanan aktarım hızını artırma
Azure Cosmos DB'de sağlanan aktarım hızınız İstek Birimleri (RU) cinsinden ölçülür. 5 RU aktarım hızı kullanan bir sorgunuz olduğunu varsayın. Örneğin, 1.000 RU sağlarsanız, bu sorguyu saniyede 200 kez çalıştırabilirsiniz. Yeterli aktarım hızı olmadığında sorguyu çalıştırmayı denediyseniz, Azure Cosmos DB, istekleri sınırlandırır. MongoDB için Azure Cosmos DB API'si, kısa bir süre bekledikten sonra bu sorguyu otomatik olarak yeniden dener. Kısıtlanmış istekler daha uzun sürer, bu nedenle sağlanan aktarım hızını artırmak sorgu gecikme süresini iyileştirebilir.
Bu değer estimatedDelayFromRateLimitingInMilliseconds
, aktarım hızını artırırsanız olası gecikme süresi avantajlarına ilişkin bir anlayış sağlar.
Sonraki adımlar
- Sorgu performansı sorunlarını giderme (NoSQL için API)
- SSR ile hız sınırlamasını önleme
- MongoDB için Azure Cosmos DB API’sinde dizin oluşturmayı yönetme
- Azure Cosmos DB'ye geçiş için kapasite planlaması yapmaya mı çalışıyorsunuz? Kapasite planlaması için mevcut veritabanı kümeniz hakkındaki bilgileri kullanabilirsiniz.
- Tek bildiğiniz mevcut veritabanı kümenizdeki sanal çekirdek ve sunucu sayısıysa, sanal çekirdek veya vCPU kullanarak istek birimlerini tahmin etme hakkında bilgi edinin
- Geçerli veritabanı iş yükünüz için tipik istek oranlarını biliyorsanız Azure Cosmos DB kapasite planlayıcısı kullanarak istek birimlerini tahmin etme hakkında bilgi edinin
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin