Azure Cosmos DB ile sorgu performansını ayarlama
UYGULANANLAR: NoSQL
Azure Cosmos DB, şema veya ikincil dizinlere gerek kalmadan verileri sorgulamak için NoSQL için bir API sağlar. Bu makalede geliştiriciler için aşağıdaki bilgiler sağlanır:
- Azure Cosmos DB'nin SQL sorgu yürütme işleminin nasıl çalıştığına ilişkin üst düzey ayrıntılar
- Sorgu performansı için ipuçları ve en iyi yöntemler
- Sorgu performansında hata ayıklamak için SQL sorgu yürütme ölçümlerini kullanma örnekleri
SQL sorgusu yürütme hakkında
Azure Cosmos DB'de veriler kapsayıcılarda depolanır ve bu da herhangi bir depolama boyutuna veya istek aktarım hızına kadar büyüyebilir. Azure Cosmos DB, verilerin büyümesi veya sağlanan aktarım hızındaki artışları işlemek için örtüler altında verileri fiziksel bölümler arasında sorunsuz bir şekilde ölçeklendirir. REST API'yi veya desteklenen SQL SDK'larından birini kullanarak herhangi bir kapsayıcıya SQL sorguları düzenleyebilirsiniz.
Bölümlemeye kısa bir genel bakış: Verilerin fiziksel bölümler arasında nasıl bölüneceğini belirleyen "şehir" gibi bir bölüm anahtarı tanımlarsınız. Tek bir bölüm anahtarına ait veriler (örneğin, "city" == "Seattle") fiziksel bir bölümde depolanır ve tek bir fiziksel bölüm birden çok bölüm anahtarından verileri depolayabilir. Bir bölüm depolama sınırına ulaştığında, hizmet bölümü sorunsuz bir şekilde iki yeni bölüme böler. Veriler, tek bir bölüm anahtarı için tüm verileri bir arada tutarak yeni bölümler arasında eşit olarak dağıtılır. Bölümler geçici olduğundan, API'ler bölüm anahtarı aralığının özetini kullanır ve bu da bölüm anahtarı karmalarının aralıklarını belirtir.
Azure Cosmos DB'ye bir sorgu gönderdiğinizde SDK şu mantıksal adımları gerçekleştirir:
- Sorgu yürütme planını belirlemek için SQL sorgusunu ayrıştırın.
- Sorgu, gibi
SELECT * FROM c WHERE c.city = "Seattle"
bölüm anahtarına karşı bir filtre içeriyorsa, tek bir bölüme yönlendirilir. Sorgunun bölüm anahtarında bir filtresi yoksa, tüm bölümlerde yürütülür ve her bölümden elde edilen sonuçlar istemci tarafında birleştirilir. - Sorgu, istemci yapılandırmasına bağlı olarak her bölümde seri veya paralel olarak yürütülür. Her bölümde sorgu, sorgu karmaşıklığı, yapılandırılmış sayfa boyutu ve koleksiyonun sağlanan aktarım hızına bağlı olarak bir veya daha fazla gidiş dönüş yapabilir. Her yürütme, sorgu yürütme ve sorgu yürütme istatistikleri tarafından kullanılan istek birimi sayısını döndürür.
- SDK, bölümler arasında sorgu sonuçlarını özetler. Örneğin, sorgu bölümler arasında ORDER BY içeriyorsa, tek tek bölümlerden elde edilen sonuçlar, sonuçları genel olarak sıralanmış düzende döndürmek için birleştirilerek sıralanır. Sorgu gibi
COUNT
bir toplama ise, tek tek bölümlerdeki sayılar toplayarak genel sayıyı oluşturur.
SDK'lar sorgu yürütme için çeşitli seçenekler sağlar. Örneğin, .NET'te bu seçenekler sınıfında kullanılabilir QueryRequestOptions
. Aşağıdaki tabloda bu seçenekler ve bunların sorgu yürütme süresini nasıl etkilediği açıklanmaktadır.
Seçenek | Açıklama |
---|---|
EnableScanInQuery |
Yalnızca istenen filtre yolu için dizin oluşturma devre dışı bırakıldıysa geçerlidir. Dizin oluşturmayı geri çevirdiyseniz ve tam tarama kullanarak sorgu çalıştırmak istiyorsanız true olarak ayarlanmalıdır. |
MaxItemCount |
Sunucuya gidiş dönüş başına döndürülecek en fazla öğe sayısı. Sunucunun döndürülecek öğe sayısını yönetmesine izin vermek için -1 olarak ayarlayabilirsiniz. |
MaxBufferedItemCount |
Paralel sorgu yürütme sırasında istemci tarafında arabelleğe alınabilecek en fazla öğe sayısı. Pozitif özellik değeri, arabelleğe alınan öğelerin sayısını ayarlanan değerle sınırlar. Sistemin arabelleğe alınacak öğe sayısına otomatik olarak karar vermesine izin vermek için bunu 0'dan küçük olarak ayarlayabilirsiniz. |
MaxConcurrency |
Paralel sorgu yürütme sırasında istemci tarafında çalıştırılacak eşzamanlı işlemlerin sayısını alır veya ayarlar. Pozitif özellik değeri, eş zamanlı işlemlerin sayısını ayarlanan değerle sınırlar. Sistemin çalıştırılacak eşzamanlı işlem sayısına otomatik olarak karar vermesine izin vermek için bunu 0'dan küçük olarak ayarlayabilirsiniz. |
PopulateIndexMetrics |
Sorgu altyapısının mevcut dizinleri nasıl kullandığını ve olası yeni dizinleri nasıl kullanabileceğini anlamak için dizin ölçümlerinin toplanmasını sağlar. Bu seçenek ek yük oluşturur, bu nedenle yalnızca yavaş sorgularda hata ayıklarken etkinleştirilmelidir. |
ResponseContinuationTokenLimitInKb |
Sunucu tarafından döndürülen devamlılık belirtecinin en büyük boyutunu sınırlayabilirsiniz. Uygulama ana bilgisayarınızın yanıt üst bilgisi boyutuyla ilgili sınırları varsa bunu ayarlamanız gerekebilir, ancak sorgu için kullanılan genel süreyi ve RU'ları artırabilir. |
Örneğin, .NET SDK'sı kullanılarak bölümlenmiş /city
bir kapsayıcıda bir sorgu aşağıda verilmiştır:
QueryDefinition query = new QueryDefinition("SELECT * FROM c WHERE c.city = 'Seattle'");
QueryRequestOptions options = new QueryRequestOptions()
{
MaxItemCount = -1,
MaxBufferedItemCount = -1,
MaxConcurrency = -1,
PopulateIndexMetrics = true
};
FeedIterator<dynamic> feedIterator = container.GetItemQueryIterator<dynamic>(query);
FeedResponse<dynamic> feedResponse = await feedIterator.ReadNextAsync();
Her sorgu yürütmesi, sorgu isteği seçenekleri ve gövdedeki SQL sorgusu için üst bilgileri ayarlanmış bir REST API'ye POST
karşılık gelir. REST API istek üst bilgileri ve seçenekleri hakkında ayrıntılı bilgi için bkz . REST API kullanarak kaynakları sorgulama.
Sorgu performansı için en iyi yöntemler
Aşağıdaki faktörler genellikle Azure Cosmos DB sorgu performansı üzerinde en büyük etkiye sahiptir. Bu makaledeki bu faktörlerin her birini daha ayrıntılı olarak inceleyeceğiz.
Faktör | İpucu |
---|---|
Sağlanan aktarım hızı | Sorgu başına RU'yu ölçün ve sorgularınız için gerekli sağlanan aktarım hızına sahip olduğunuzdan emin olun. |
Bölümleme ve bölüm anahtarları | Düşük gecikme süresi için filtre yan tümcesindeki bölüm anahtarı değeriyle sorguları tercih edin. |
SDK ve sorgu seçenekleri | Doğrudan bağlantı gibi en iyi SDK uygulamalarını izleyin ve istemci tarafı sorgu yürütme seçeneklerini ayarlayın. |
Ağ gecikmesi | Gecikme süresini azaltmak için uygulamanızı Azure Cosmos DB hesabınızla aynı bölgede çalıştırın. |
Dizin oluşturma ilkesi | Sorgu için gerekli dizin oluşturma yollarına/ilkesine sahip olduğunuzdan emin olun. |
Sorgu yürütme ölçümleri | Sorgu ve veri şekillerinin olası yeniden yazmalarını belirlemek için sorgu yürütme ölçümlerini analiz edin. |
Sağlanan aktarım hızı
Azure Cosmos DB'de her biri saniye başına istek birimleri (RU) cinsinden ayrılmış aktarım hızına sahip veri kapsayıcıları oluşturursunuz. 1 KB'lık bir belgenin okunmasının bir RU'dur ve her işlem (sorgular dahil) karmaşıklığı temel alınarak sabit sayıda RU'ya normalleştirilir. Örneğin, kapsayıcınız için sağlanan 1000 RU/sn'niz varsa ve bunun gibi SELECT * FROM c WHERE c.city = 'Seattle'
bir sorgunuz 5 RU tüketiyorsa, (1000 RU/sn) / (5 RU/sorgu) = saniyede bu sorgulardan 200 tane yürütebilirsiniz.
200'den fazla sorgu/sn (veya sağlanan tüm RU'ları doyuran başka işlemler) gönderirseniz, hizmet gelen istekleri hız sınırlamaya başlar. SDK'lar geri alma/yeniden deneme gerçekleştirerek hız sınırlamayı otomatik olarak işler, bu nedenle bu sorgular için daha yüksek gecikme süresi fark edebilirsiniz. Sağlanan aktarım hızını gerekli değere yükseltmek sorgu gecikme sürenizi ve aktarım hızınızı artırır.
İstek birimleri hakkında daha fazla bilgi edinmek için bkz . İstek birimleri.
Bölümleme ve bölüm anahtarları
Azure Cosmos DB ile verileri okumak için aşağıdaki senaryolar genellikle en hızlı/en verimli olandan en yavaş/en az verimli olana kadar sıralanır.
- Okunan nokta olarak da bilinen tek bir bölüm anahtarında ve öğe kimliğinde GET
- Tek bir bölüm anahtarında filtre yan tümcesi içeren sorgu
- Herhangi bir özellikte eşitlik veya aralık filtresi yan tümcesi olan sorgu
- Filtre olmadan sorgulama
Tüm bölümlerde yürütülmesi gereken sorgular daha yüksek gecikme süresine sahiptir ve daha yüksek RU kullanabilir. Her bölümün tüm özelliklere göre otomatik dizin oluşturma özelliği olduğundan, bu durumda sorgu dizinden verimli bir şekilde sunulabilir. Paralellik seçeneklerini kullanarak bölümlere yayılan sorguları daha hızlı hale getirebilirsiniz.
Bölümleme ve bölüm anahtarları hakkında daha fazla bilgi edinmek için bkz . Azure Cosmos DB'de bölümleme.
SDK ve sorgu seçenekleri
SDK'larımızı kullanarak Azure Cosmos DB'den en iyi istemci tarafı performansını elde etmek için bkz . sorgu performansı ipuçları ve performans testi .
Ağ gecikmesi
Genel dağıtımı ayarlama ve en yakın bölgeye bağlanma hakkında bilgi için bkz. Azure Cosmos DB genel dağıtımı. Birden çok gidiş dönüş yapmanız veya sorgudan büyük bir sonuç kümesi almanız gerektiğinde ağ gecikmesinin sorgu performansı üzerinde önemli bir etkisi vardır.
Sorgu yürütme ölçümlerini kullanarak sorguların sunucu yürütme süresini alabilir ve sorgu yürütme için harcanan zamanı ağ aktarımında harcanan zamandan ayırt edebilirsiniz.
Dizin oluşturma ilkesi
Bkz . Dizin oluşturma yolları, türleri ve modları için dizin oluşturma ilkesini yapılandırma ve bunların sorgu yürütmeyi nasıl etkiledikleri. Varsayılan olarak, Azure Cosmos DB tüm verilere otomatik dizin oluşturma uygular ve dizeler ve sayılar için aralık dizinlerini kullanır ve bu da eşitlik sorguları için etkilidir. Yüksek performanslı ekleme senaryoları için, her ekleme işleminin RU maliyetini azaltmak için yolları dışlamanız önerilir.
Her sorgu için hangi dizinlerin kullanıldığını ve sorgu performansını geliştirecek eksik dizinler olup olmadığını belirlemek için dizin ölçümlerini kullanabilirsiniz.
Sorgu yürütme ölçümleri
İstek tanılamasında her sorgu yürütmesi için ayrıntılı ölçümler döndürülür. Bu ölçümler sorgu yürütme sırasında zamanın nereye harcandığı açıklanır ve gelişmiş sorun gidermeyi etkinleştirir.
Sorgu ölçümlerini alma hakkında daha fazla bilgi edinin.
Metric | Unit | Açıklama |
---|---|---|
TotalTime |
milisaniye | Toplam sorgu yürütme süresi |
DocumentLoadTime |
milisaniye | Belgeleri yüklemek için harcanan süre |
DocumentWriteTime |
milisaniye | Çıktı belgelerini yazmak ve serileştirmek için harcanan süre |
IndexLookupTime |
milisaniye | Fiziksel dizin katmanında harcanan süre |
QueryPreparationTime |
milisaniye | Sorgu hazırlanırken harcanan süre |
RuntimeExecutionTime |
milisaniye | Toplam sorgu çalışma zamanı yürütme süresi |
VMExecutionTime |
milisaniye | Sorguyu yürütürken sorgu çalışma zamanında harcanan süre |
OutputDocumentCount |
count | Sonuç kümesindeki çıktı belgelerinin sayısı |
OutputDocumentSize |
count | Çıktısı alınan belgelerin bayt cinsinden toplam boyutu |
RetrievedDocumentCount |
count | Alınan belgelerin toplam sayısı |
RetrievedDocumentSize |
bayt | Alınan belgelerin bayt cinsinden toplam boyutu |
IndexHitRatio |
oran [0,1] | Filtreyle eşleşen belge sayısının yüklenen belge sayısına oranı |
İstemci SDK'ları, her bölümde sorguyu sunmak için dahili olarak birden çok sorgu isteğinde bulunabilir. Toplam sonuç en fazla öğe sayısı istek seçeneğini aşarsa, sorgu bölüm için sağlanan aktarım hızını aşarsa, sorgu yükü sayfa başına maksimum boyuta ulaşırsa veya sorgu sistem tarafından ayrılan zaman aşımı sınırına ulaşırsa istemci bölüm başına birden fazla çağrı yapar. Kısmi her sorgu yürütmesi, bu sayfa için sorgu ölçümlerini döndürür.
Bazı örnek sorgular ve sorgu yürütmeden döndürülen ölçümlerden bazılarının nasıl yorum yapılacağı aşağıda verilmiştir:
Sorgu | Örnek Ölçüm | Açıklama |
---|---|---|
SELECT TOP 100 * FROM c |
"RetrievedDocumentCount": 101 |
Alınan belge sayısı TOP yan tümcesi ile eşleşecek şekilde 100+1'dir. Sorgu süresi çoğunlukla içinde ve DocumentLoadTime tarama olduğundan harcanmış WriteOutputTime olur. |
SELECT TOP 500 * FROM c |
"RetrievedDocumentCount": 501 |
RetrievedDocumentCount artık daha yüksektir (TOP yan tümcesi ile eşleşmesi için 500+1). |
SELECT * FROM c WHERE c.N = 55 |
"IndexLookupTime": "00:00:00.0009500" |
Üzerinde bir dizin araması olduğundan, anahtar araması için IndexLookupTime içinde yaklaşık 0,9 ms harcandı /N/? . |
SELECT * FROM c WHERE c.N > 55 |
"IndexLookupTime": "00:00:00.0017700" |
Üzerinde bir dizin araması olduğundan, bir aralık taraması için IndexLookupTime içinde biraz daha fazla zaman (1,7 ms) harcandı /N/? . |
SELECT TOP 500 c.N FROM c |
"IndexLookupTime": "00:00:00.0017700" |
Önceki sorgularda DocumentLoadTime harcanan süre aynı, ancak yalnızca bir özelliği yansıttığımız için daha düşük DocumentWriteTime . |
SELECT TOP 500 udf.toPercent(c.N) FROM c |
"RuntimeExecutionTime": "00:00:00.2136500" |
UDF'nin her değeri üzerinde yürütülmesi için RuntimeExecutionTime yaklaşık 213 ms harcanıyor c.N . |
SELECT TOP 500 c.Name FROM c WHERE STARTSWITH(c.Name, 'Den') |
"IndexLookupTime": "00:00:00.0006400", "RuntimeExecutionTime": "00:00:00.0074100" |
üzerinde yaklaşık 0,6 ms harcandı IndexLookupTime /Name/? . içindeki RuntimeExecutionTime sorgu yürütme süresinin çoğu (~7 ms). |
SELECT TOP 500 c.Name FROM c WHERE STARTSWITH(LOWER(c.Name), 'den') |
"IndexLookupTime": "00:00:00", "RetrievedDocumentCount": 2491, "OutputDocumentCount": 500 |
Sorgu, kullandığından LOWER tarama olarak gerçekleştirilir ve 2491 alınan belgenin 500'ünün döndürülür. |
Sonraki adımlar
- Desteklenen SQL sorgu işleçleri ve anahtar sözcükleri hakkında bilgi edinmek için bkz . SQL sorgusu.
- İstek birimleri hakkında bilgi edinmek için bkz . İstek birimleri.
- Dizin oluşturma ilkesi hakkında bilgi edinmek için bkz. dizin oluşturma ilkesi