Sorgu performansını optimize etme

Yavaş sorgularla ilgili sorunları gidermek için Query Explain'i kullanarak sorgu yürütme planını ve çalışma zamanı yürütme profilini alın. Aşağıdaki bölümde, yürütme profiline bağlı olarak sorgu performansını optimize etmek için uygulayabileceğiniz adımlar açıklanmaktadır:

Sonuç sayısını sınırlama

Sorgunun çok sayıda doküman döndürüp döndürmediğini belirlemek için yürütme ağacındaki döndürülen kayıtlar alanını kullanın. limit(...) aşamasını kullanarak döndürülen doküman sayısını sınırlandırabilirsiniz. Bu, sonuçlar ağ üzerinden istemcilere döndürüldüğünde sonuçların serileştirilmiş bayt boyutunu azaltır. Limit düğümünden önce bir MajorSort düğümünün geldiği durumlarda sorgu motoru, Limit ve MajorSort düğümlerini birleştirebilir ve tam bellek içi somutlaştırma ve sıralamayı TopN sıralamasıyla değiştirerek sorgu için bellek gereksinimini azaltabilir.

Sonuç dokümanının boyutunu sınırlama

Yalnızca gerekli alanları döndürmek için select(...) kullanarak veya çok büyük alanları silmek için remove_fields(...) kullanarak döndürülen belgenin boyutunu sınırlayabilirsiniz. Bu, ara sonuçları işlemenin işlem ve bellek maliyetini ve sonuçlar ağ üzerinden istemcilere döndürüldüğünde sonuçların serileştirilmiş bayt boyutunu azaltmaya yardımcı olur. Sorguda başvurulan tüm alanların normal bir dizin tarafından kapsandığı durumlarda bu, sorgunun dizin taraması tarafından tamamen kapsanmasını sağlayarak birincil depolama alanından belge alma ihtiyacını ortadan kaldırır.

Dizinleri kullanma

Dizinleri oluşturmak ve optimize etmek için aşağıdaki talimatları uygulayın.

Sorgunun dizin kullanıp kullanmadığını belirleme

Yürütme ağacındaki yaprak düğümleri kontrol ederek sorgunun bir dizin kullanıp kullanmadığını belirleyebilirsiniz. Yürütme ağacının yaprak düğümü bir TableScan düğümü ise sorgu bir dizin kullanmıyor ve birincil depolama alanındaki dokümanları tarıyor demektir. Dizin kullanılıyorsa yürütme ağacının yaprak düğümünde dizin kimliği ve dizin alanları gösterilir.

Daha iyi bir dizin belirleme

Dizin, sorgu motorunun birincil depolama alanından getirmesi gereken belge sayısını azaltabiliyorsa veya alan sıralaması sorgunun sıralama şartını karşılayabiliyorsa sorgu için kullanışlıdır.

Sorgu için bir dizin kullanılıyorsa ancak sorgu motoru hâlâ birçok belgeyi getirip atıyorsa (bu durum, birçok kayıt döndüren bir Tarama düğümünün ardından az sayıda kayıt döndüren bir Filtre düğümü ile tanımlanır) bu, dizin kullanılarak karşılanan sorgu yükleminin seçici olmadığını gösterir. Daha uygun bir dizin oluşturmak için Dizin oluşturma başlıklı makaleyi inceleyin.

Sorgu için bir dizin kullanılmasına rağmen sorgu motoru, sorgu yürütme ağacındaki bir MajorSort düğümü tarafından tanımlandığı şekilde sonuç kümesini bellek içinde yeniden sıralamaya devam ediyorsa bu durum, kullanılan dizinin sorgunun sıralama şartını karşılamak için kullanılamayacağını gösterir. Daha uygun bir dizin oluşturmak için sonraki bölüme bakın.

Dizin oluşturma

Dizin oluşturmak için dizin yönetimi belgelerini inceleyin. Sorgunuzun dizinleri kullanabilmesi için aşağıdaki sırayla alanlar içeren normal (çoklu anahtar olmayan) dizinler oluşturun:

  1. Eşitlik operatörlerinde kullanılacak tüm alanlar. Sorgular arasında yeniden kullanım şansını en üst düzeye çıkarmak için alanları, sorgular arasındaki eşitlik operatörlerinde alanların oluşma sırasına göre azalan düzende sıralayın.
  2. Sıralanacak tüm alanlar (aynı sırada).
  3. Sorgu kısıtlaması seçiciliğinin azalan sırasına göre aralık veya eşitsizlik operatörlerinde kullanılacak alanlar.
  4. Dizindeki bir sorgunun parçası olarak döndürülecek alanlar: Bu tür alanların dizine eklenmesi, dizinin sorguyu kapsamasını sağlar ve birincil depolama alanından doküman getirme ihtiyacını ortadan kaldırır.

Dizin veya tablo taramasını zorunlu kılma

Cloud Firestore sorgusu yaptığınızda, sorguyu daha verimli hale getirme olasılığı yüksek olan tüm dizinler otomatik olarak kullanılır. Bu nedenle, sorgularınız için dizin belirtmeniz gerekmez. Ancak iş yükünüz için kritik olan sorgularda daha tutarlı performans için forceIndex seçeneğini kullanmanızı öneririz.

Bazı durumlarda Cloud Firestore, sorgu gecikmesinin artmasına neden olan bir dizin seçebilir. Performans düşüşleriyle ilgili sorun giderme adımlarını uyguladıysanız ve sorgu için farklı bir dizin denemenin mantıklı olduğunu onayladıysanız forceIndex seçeneğini kullanarak dizini belirtebilirsiniz.

Cloud Firestore'ın varsayılan sorgu planını geçersiz kılmak ve kullanılacak bir dizin belirtmek ya da tablo taramasını zorunlu kılmak için ardışık düzen işlemlerindeki herhangi bir giriş aşamasında forceIndex seçeneğini kullanabilirsiniz.

Belirli bir dizini zorunlu kılma

Sorguyu belirli bir dizini kullanmaya zorlamak için dizin kimliğini forceIndex seçeneğine dize olarak sağlayın. Dizin kimliğini konsoldan veya hata mesajlarından bulabilirsiniz.

Aşağıdaki örnekte, planlayıcı CICAgOi36pgK kimlikli dizini kullanmaya zorlanmaktadır:

Node.js
// Force Planner to use Index ID CICAgOi36pgK
await db.pipeline()
  .collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" })
  .limit(100)
  .execute();
Java
// Force Planner to use Index ID CICAgOi36pgK
Pipeline.Snapshot results1 =
    firestore.pipeline()
      .collectionGroup("customers", new CollectionGroupOptions()
          .withHints(new CollectionHints().withForceIndex("CICAgOi36pgK")))
      .limit(100)
      .execute().get();
Go
// Force Planner to use Index ID CICAgOi36pgK
snapshot1 := client.Pipeline().
	CollectionGroup("customers", firestore.WithForceIndex("CICAgOi36pgK")).
	Limit(100).
	Execute(ctx)

Belirli bir dizini zorunlu kılmanın bazı kullanım alanları şunlardır:

  • Farklı dizinlerin performansını test etme
  • Sorgu için belirli ve en uygun olduğu bilinen bir dizinin kullanılmasını sağlama
  • Varsayılan seçimi belirli bir sorgu için yetersiz olduğunda optimize ediciyi geçersiz kılma.

Belirtilen dizin bulunamazsa sorgu başarısız olur.

Tablo taramasını zorunlu kılma

Tablo tarama, ikincil dizin kullanmadan koleksiyondaki veya koleksiyon grubundaki dokümanları okur. Tablo taramasını zorunlu kılmak için forceIndex değerini primary olarak ayarlayın.

Aşağıdaki örnekte tablo taraması zorunlu kılınmıştır:

// Force Planner to only do a Full-Table Scan
db.pipeline()
  .collectionGroup({ collectionId: "customers", forceIndex: "primary" })
  .limit(100)

Aşağıdaki durumlarda tablo taraması kullanabilirsiniz:

  • Dizin ek yükünün gerekçelendirilmediği çok küçük koleksiyonlar için.
  • Bir koleksiyondaki belgelerin çoğuna erişen sorgular için.
  • Hata ayıklama ve performans karşılaştırmaları için kullanılır.

Sorgu Açıklaması ile forceIndex kullanma

forceIndex'nin etkilerini gözlemlemek için explain veya analyze modlarında Query Explain'i kullanabilirsiniz:

  • Dizin kimliği için yürütme ağacının yaprak düğümlerini kontrol ederek Cloud Firestore sorgusunun forceIndex içinde belirtilen dizini kullandığını doğrulayın.
  • forceIndex: "primary" kullanırken planda bir TableScan düğümünün göründüğünü doğrulayın.
  • analyze moduyla, sorgu performansında ince ayar yapmak için gecikme, taranan dokümanlar ve taranan dizin girişleri gibi performans metriklerini forceIndex ile ve olmadan karşılaştırın.

forceIndex için en iyi uygulamalar

forceIndex, sorgu yürütme üzerinde daha fazla kontrol sağlasa da Cloud Firestore'in sorgu optimize edicisi çoğu kullanım alanı için genellikle etkilidir. forceIndex özelliğini kullanırken aşağıdaki en iyi uygulamalardan yararlanabilirsiniz:

  • forceIndex özelliğini dikkatli kullanın. Varsayılan sorgu planında optimum performans elde edemiyorsanız dizini zorlamadan önce sorunu teşhis etmek için Query Explain'i kullanın.
  • forceIndex kullanırken sorgularınızın performans ve maliyet özelliklerini anlamak için sorgularınızı gerçekçi veri hacimleriyle test ettiğinizden emin olun.
  • Üretim ortamlarındaki büyük koleksiyonlarda forceIndex: "primary" kullanmaktan kaçının.

Query Explain ile yürütülen bir sorgunun çıkışı hakkında daha fazla bilgi için Sorgu yürütme referansı başlıklı makaleyi inceleyin.