Sorgu Açıklaması'nı kullanarak sorgu performansını anlama

Query Explain, arka uca Cloud Firestore sorguları göndermenize ve karşılığında arka uç sorgu yürütme işlemiyle ilgili ayrıntılı performans istatistikleri almanıza olanak tanır. Birçok ilişkisel veritabanı sistemindeki EXPLAIN [ANALYZE] işlemi gibi çalışır.

Query Explain istekleri, Firestore sunucu istemci kitaplıkları kullanılarak gönderilebilir.

Query Explain sonuçları, sorgularınızın nasıl yürütüldüğünü anlamanıza yardımcı olur. Ayrıca verimsizlikleri ve sunucu tarafındaki olası darboğazların konumunu gösterir.

Sorgu Açıklaması:

  • Sorgu planlama aşamasıyla ilgili analizler sunar. Böylece sorgu dizinlerinizi ayarlayabilir ve verimliliği artırabilirsiniz.
  • Analiz seçeneğini kullanarak maliyetinizi ve performansınızı sorgu bazında anlayabilir ve farklı sorgu kalıplarını hızlıca yineleyerek kullanımlarını optimize edebilirsiniz.

Query Explain seçeneklerini anlama: varsayılan ve analiz

Sorgu Açıklama işlemleri, varsayılan seçenek veya analiz seçeneği kullanılarak gerçekleştirilebilir.

Varsayılan seçenekte Query Explain, sorguyu planlar ancak yürütme aşamasını atlar. Bu işlem, planlayıcı aşaması bilgilerini döndürür. Bu özelliği kullanarak bir sorgunun gerekli dizinlere sahip olup olmadığını kontrol edebilir ve hangi dizinlerin kullanıldığını anlayabilirsiniz. Bu sayede, örneğin belirli bir sorgunun birçok farklı dizini kesiştirmek yerine bileşik dizin kullandığını doğrulayabilirsiniz.

Analiz seçeneğiyle Query Explain, sorguyu hem planlar hem de yürütür. Bu, daha önce bahsedilen tüm planlayıcı bilgilerini ve sorgu yürütme çalışma zamanından istatistikleri döndürür. Bu, sorgunun fatura bilgilerinin yanı sıra sorgu yürütmeyle ilgili sistem düzeyinde analizleri de içerir. Maliyet ve gecikmeyi optimize etmek amacıyla çeşitli sorgu ve dizin yapılandırmalarını test etmek için bu aracı kullanabilirsiniz.

Sorgu Açıklama'nın maliyeti nedir?

Query Explain'i varsayılan seçenekle kullandığınızda dizin veya okuma işlemi yapılmaz. Sorgunun karmaşıklığına bakılmaksızın bir okuma işlemi ücretlendirilir.

Query Explain'i analiz seçeneğiyle kullandığınızda dizin oluşturma ve okuma işlemleri gerçekleştirilir. Bu nedenle, sorgu için her zamanki gibi ücretlendirilirsiniz. Analiz etkinliği için ek ücret alınmaz, yalnızca yürütülen sorgu için her zamanki ücret alınır.

Varsayılan seçenekle Query Explain'i kullanma

Varsayılan seçenek isteği göndermek için istemci kitaplıklarını kullanabilirsiniz.

İsteklerin, normal sorgu işlemleriyle aynı izinler kullanılarak IAM ile kimlik doğrulamasından geçirildiğini unutmayın. Firebase Authentication gibi diğer kimlik doğrulama teknikleri yoksayılır. Daha fazla bilgi için Sunucu istemci kitaplıkları için IAM kılavuzuna bakın.

Java (Yönetici)

Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();

    
Düğüm (Yönetici)

const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'false' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;

    

Yanıtın tam biçimi, yürütme ortamına bağlıdır. Döndürülen sonuçlar JSON'a dönüştürülebilir. Örneğin:

{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

Daha fazla bilgi için Sorgu Açıklama raporu referansı'na bakın.

Sorgu Açıklama'yı analiz seçeneğiyle kullanma

Analiz seçeneği isteği göndermek için istemci kitaplıklarını kullanabilirsiniz.

İsteklerin, normal sorgu işlemleriyle aynı izinler kullanılarak IAM ile kimlik doğrulamasından geçirildiğini unutmayın. Firebase Authentication gibi diğer kimlik doğrulama teknikleri yoksayılır. Daha fazla bilgi için Sunucu istemci kitaplıkları için IAM kılavuzuna bakın.

Java (Yönetici)

Query q = db.collection("col").whereGreaterThan("a", 1);

ExplainOptions options = ExplainOptions.builder().setAnalyze(true).build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();

ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
ExecutionStats stats = metrics.getExecutionStats();

    
Düğüm (Yönetici)

const q = db.collection('col').where('country', '=', 'USA');

const options = { analyze : 'true' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;
const indexesUsed = plan.indexesUsed;
const stats = metrics.executionStats;

    

Aşağıdaki örnekte, planInfo nesnesine ek olarak döndürülen stats nesnesi gösterilmektedir. Yanıtın tam biçimi, yürütme ortamına bağlıdır. Örnek yanıt JSON biçimindedir.

{
    "resultsReturned": "5",
    "executionDuration": "0.100718s",
    "readOperations": "5",
    "debugStats": {
               "index_entries_scanned": "95000",
               "documents_scanned": "5"
               "billing_details": {
                     "documents_billable": "5",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }

}

Daha fazla bilgi için Sorgu Açıklama raporu referansı'na bakın.

Sonuçları yorumlama ve düzenlemeler yapma

Filmleri türe ve yapım ülkesine göre sorguladığımız örnek bir senaryoya bakalım.

Örnek olarak, bu SQL sorgusunun eşdeğerini varsayalım.

SELECT *
FROM /movies
WHERE category = 'Romantic' AND country = 'USA';

Analiz seçeneğini kullanırsak döndürülen metrikler, sorgunun iki tek alanlı dizinde ((category ASC, __name__ ASC) ve (country ASC, __name__ ASC)) çalıştığını gösterir. 16.500 dizin girişini tarar ancak yalnızca 1.200 doküman döndürür.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

// Output query status
{
    "resultsReturned": "1200",
    "executionDuration": "0.118882s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "16500",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}

Sorguyu yürütme performansını optimize etmek için tamamen kapsanan bir bileşik dizin (category ASC, country ASC, __name__ ASC) oluşturabilirsiniz.

Sorguyu analiz seçeneğiyle tekrar çalıştırdığımızda, bu sorgu için yeni oluşturulan dizinin seçildiğini ve sorgunun çok daha hızlı ve verimli bir şekilde çalıştığını görebiliriz.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, country ASC,  __name__ ASC)"}
    ]
}

// Output query stats
{
    "resultsReturned": "1200",
    "executionDuration": "0.026139s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "1200",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}