Fazlalık Getirme kötü modeliExtraneous Fetching antipattern

Bir iş işlemi için gerekenden daha fazla veri alınması, gereksiz G/Ç ek yüküne neden olabilir ve yanıt hızını azaltabilir.Retrieving more data than needed for a business operation can result in unnecessary I/O overhead and reduce responsiveness.

Sorun açıklamasıProblem description

Bu kötü model, uygulama ihtiyaç duyabileceği tüm verileri alarak G/Ç isteklerinin sayısını en aza indirmeye çalışırsa ortaya çıkabilir.This antipattern can occur if the application tries to minimize I/O requests by retrieving all of the data that it might need. Bu durum genellikle Geveze G/Ç kötü modelinin fazlasıyla telafi edilmesinin bir sonucudur.This is often a result of overcompensating for the Chatty I/O antipattern. Örneğin, uygulama bir veritabanındaki her ürüne ait ayrıntıları getirebilir.For example, an application might fetch the details for every product in a database. Ancak kullanıcının ayrıntıların yalnızca bir kısmına ihtiyacı olabilir (bazı ayrıntılar müşterilerle ilgili olmayabilir). Ayrıca, kullanıcının büyük olasılıkla ürünlerin tamamını aynı anda görmesi gerekmiyordur.But the user may need just a subset of the details (some may not be relevant to customers), and probably doesn't need to see all of the products at once. Kullanıcı tüm kataloğa göz atıyorsa bile sonuçları, örneğin bir defada 20 tanesi gösterilecek şekilde sayfalara bölmek mantıklı olacaktır.Even if the user is browsing the entire catalog, it would make sense to paginate the results — showing 20 at a time, for example.

Bu sorunun bir diğer kaynağı da kötü programlama veya tasarım uygulamalarının kullanılmasıdır.Another source of this problem is following poor programming or design practices. Örneğin, aşağıdaki kod Entity Framework’ü kullanarak her ürüne ait tüm ayrıntıları getiriyor.For example, the following code uses Entity Framework to fetch the complete details for every product. Kod daha sonra sonuçları filtreleyerek alanların yalnızca bir bölümünü döndürüp kalanları atıyor.Then it filters the results to return only a subset of the fields, discarding the rest. Örneğin tamamını burada bulabilirsiniz.You can find the complete sample here.

public async Task<IHttpActionResult> GetAllFieldsAsync()
{
    using (var context = new AdventureWorksContext())
    {
        // Execute the query. This happens at the database.
        var products = await context.Products.ToListAsync();

        // Project fields from the query results. This happens in application memory.
        var result = products.Select(p => new ProductInfo { Id = p.ProductId, Name = p.Name });
        return Ok(result);
    }
}

Sıradaki örnekte, uygulama bir toplama işlemi gerçekleştirmek için veri alıyor. Ancak, bu toplama işlemi veritabanı tarafından yapılabilir.In the next example, the application retrieves data to perform an aggregation that could be done by the database instead. Uygulama, toplam satış rakamını hesaplamak için satılan tüm siparişlere ait her kaydı alıyor ve toplamı bu kayıtlar üzerinden hesaplıyor.The application calculates total sales by getting every record for all orders sold, and then computing the sum over those records. Örneğin tamamını burada bulabilirsiniz.You can find the complete sample here.

public async Task<IHttpActionResult> AggregateOnClientAsync()
{
    using (var context = new AdventureWorksContext())
    {
        // Fetch all order totals from the database.
        var orderAmounts = await context.SalesOrderHeaders.Select(soh => soh.TotalDue).ToListAsync();

        // Sum the order totals in memory.
        var total = orderAmounts.Sum();
        return Ok(total);
    }
}

Sıradaki örnekte, Entity Framework’ün LINQ to Entities’i kullanma şekli nedeniyle ortaya çıkan ince bir sorun gösteriliyor.The next example shows a subtle problem caused by the way Entity Framework uses LINQ to Entities.

var query = from p in context.Products.AsEnumerable()
            where p.SellStartDate < DateTime.Now.AddDays(-7) // AddDays cannot be mapped by LINQ to Entities
            select ...;

List<Product> products = query.ToList();

Uygulama, SellStartDate değeri bir haftadan daha eski olan ürünleri bulmaya çalışıyor.The application is trying to find products with a SellStartDate more than a week old. LINQ to Entities, çoğu durumda bir where yan tümcesini veritabanı tarafından yürütülen bir SQL deyimine çevirir.In most cases, LINQ to Entities would translate a where clause to a SQL statement that is executed by the database. Ancak LINQ to Entities, bu durumda AddDays yöntemini SQL’e eşleyemiyor.In this case, however, LINQ to Entities cannot map the AddDays method to SQL. Bu nedenle, Product tablosundaki her satır döndürülüyor ve sonuçlar bellekte filtreleniyor.Instead, every row from the Product table is returned, and the results are filtered in memory.

AsEnumerable çağrısı bir sorun olduğunun ipucunu veriyor.The call to AsEnumerable is a hint that there is a problem. Bu yöntem, sonuçları bir IEnumerable arabirimine dönüştürür.This method converts the results to an IEnumerable interface. IEnumerable filtrelemeyi desteklese de filtreleme işlemi veritabanında değil, istemci tarafında yapılır.Although IEnumerable supports filtering, the filtering is done on the client side, not the database. LINQ to Entities, varsayılan olarak IQueryable arabirimini kullanır ve bu arabirim filtreleme sorumluluğunu veri kaynağına geçirir.By default, LINQ to Entities uses IQueryable, which passes the responsibility for filtering to the data source.

Sorunun çözümüHow to fix the problem

Güncel olmaktan hızla çıkabilecek veya atılabilecek büyük miktarda veri getirmekten kaçının ve yalnızca gerçekleştirilmekte olan işlem için gereken verileri getirin.Avoid fetching large volumes of data that may quickly become outdated or might be discarded, and only fetch the data needed for the operation being performed.

Bir tablonun tüm sütunlarını alıp sonra filtrelemek yerine veritabanından gereksinim duyduğunuz sütunları seçin.Instead of getting every column from a table and then filtering them, select the columns that you need from the database.

public async Task<IHttpActionResult> GetRequiredFieldsAsync()
{
    using (var context = new AdventureWorksContext())
    {
        // Project fields as part of the query itself
        var result = await context.Products
            .Select(p => new ProductInfo {Id = p.ProductId, Name = p.Name})
            .ToListAsync();
        return Ok(result);
    }
}

Benzer şekilde, toplama işlemini uygulama belleğinde değil, veritabanında gerçekleştirin.Similarly, perform aggregation in the database and not in application memory.

public async Task<IHttpActionResult> AggregateOnDatabaseAsync()
{
    using (var context = new AdventureWorksContext())
    {
        // Sum the order totals as part of the database query.
        var total = await context.SalesOrderHeaders.SumAsync(soh => soh.TotalDue);
        return Ok(total);
    }
}

Entity Framework’ü kullanırken LINQ sorgularının IEnumerable arabirimi değil, IQueryable arabirimi kullanılarak çözümlendiğinden emin olun.When using Entity Framework, ensure that LINQ queries are resolved using the IQueryableinterface and not IEnumerable. Sorguyu sadece veri kaynağına eşlenebilecek işlevleri kullanacak şekilde ayarlamanız gerekebilir.You may need to adjust the query to use only functions that can be mapped to the data source. Önceki örnek yeniden düzenlenerek AddDays yöntemi sorgudan kaldırılabilir ve böylece filtreleme işlemi veritabanı tarafından yapılır.The earlier example can be refactored to remove the AddDays method from the query, allowing filtering to be done by the database.

DateTime dateSince = DateTime.Now.AddDays(-7); // AddDays has been factored out.
var query = from p in context.Products
            where p.SellStartDate < dateSince // This criterion can be passed to the database by LINQ to Entities
            select ...;

List<Product> products = query.ToList();

Dikkat edilmesi gerekenlerConsiderations

  • Bazı durumlarda, verileri yatay olarak bölümleyerek performans artırılabilir.In some cases, you can improve performance by partitioning data horizontally. Farklı operasyonlar verilerin farklı özniteliklerine erişiyorsa yatay bölümleme uygulanması çekişmeyi azaltabilir.If different operations access different attributes of the data, horizontal partitioning may reduce contention. Genellikle, operasyonların çoğu verilerin küçük bir kısmı üzerinde çalıştırılır, bu yükün dağıtılması performansı artırabilir.Often, most operations are run against a small subset of the data, so spreading this load may improve performance. Bkz. Veri bölümleme.See Data partitioning.

  • Sınırsız sorguları desteklemesi gereken operasyonlar için sayfalandırma uygulayın ve aynı anda yalnızca sınırlı sayıda varlık getirin.For operations that have to support unbounded queries, implement pagination and only fetch a limited number of entities at a time. Örneğin, müşteri bir ürün kataloğuna göz atıyorsa aynı anda yalnızca bir sayfalık sonuç gösterebilirsiniz.For example, if a customer is browsing a product catalog, you can show one page of results at a time.

  • Mümkün olduğunda veri deposunun yerleşik özelliklerinden yararlanın.When possible, take advantage of features built into the data store. Örneğin, SQL veritabanları genellikle toplama işlevleri sağlar.For example, SQL databases typically provide aggregate functions.

  • Toplama gibi belirli bir işlevi desteklemeyen bir veri deposu kullanıyorsanız hesaplanan sonucu başka bir yerde depolayabilir ve kayıtlar eklendikçe veya güncelleştirildikçe depoladığınız değeri güncelleştirebilirsiniz. Böylece uygulamanın, her ihtiyacı olduğunda değeri baştan hesaplaması gerekmez.If you're using a data store that doesn't support a particular function, such as aggregration, you could store the calculated result elsewhere, updating the value as records are added or updated, so the application doesn't have to recalculate the value each time it's needed.

  • İsteklerin çok sayıda alan almakta olduğunu fark ederseniz bu alanların tümünün gerçekten gerekli olup olmadığını belirlemek için kaynak kodu inceleyin.If you see that requests are retrieving a large number of fields, examine the source code to determine whether all of these fields are actually necessary. Bazen bu istekler kötü tasarlanmış bir SELECT * sorgusunun sonucudur.Sometimes these requests are the result of poorly designed SELECT * query.

  • Benzer şekilde, çok sayıda varlık alan istekler uygulamanın verileri doğru şekilde filtrelemediğinin göstergesi olabilir.Similarly, requests that retrieve a large number of entities may be sign that the application is not filtering data correctly. Tüm bu varlıkların gerçekten gerekli olup olmadığını denetleyin.Verify that all of these entities are actually needed. Mümkünse, örneğin SQL’de WHERE yan tümceleri aracılığıyla veritabanı tarafı filtrelemesi kullanın.Use database-side filtering if possible, for example, by using WHERE clauses in SQL.

  • İşleme faaliyetlerinin veritabanına aktarılması her zaman en iyi seçenek değildir.Offloading processing to the database is not always the best option. Bu stratejiyi yalnızca veritabanı buna göre tasarlanmış ya da iyileştirilmiş olduğunda kullanın.Only use this strategy when the database is designed or optimized to do so. Veritabanı sistemlerinin çoğu belirli işlevler için son derece iyileştirilmiştir, ancak genel amaçlı uygulama altyapıları gibi davranmak üzere tasarlanmamıştır.Most database systems are highly optimized for certain functions, but are not designed to act as general-purpose application engines. Daha fazla bilgi için bkz. Meşgul Veritabanı kötü modeli.For more information, see the Busy Database antipattern.

Sorunu algılamaHow to detect the problem

Fazlalık getirme durumunun belirtileri, gecikme sürelerinin yüksek ve aktarım hızının düşük olmasını içerir.Symptoms of extraneous fetching include high latency and low throughput. Veriler bir veri deposundan alınıyorsa çekişmenin artması da mümkündür.If the data is retrieved from a data store, increased contention is also probable. Son kullanıcılar, uzayan yanıt süreleri veya hizmetlerin zaman aşımına uğramasından doğan hatalar bildirebilir. Bu hatalar, HTTP 500 (İç Sunucu) hataları veya HTTP 503 (Hizmet Kullanılamıyor) hataları döndürebilir.End users are likely to report extended response times or failures caused by services timing out. These failures could return HTTP 500 (Internal Server) errors or HTTP 503 (Service Unavailable) errors. Web sunucusunun olay günlüklerini inceleyin. Bu günlüklerde büyük olasılıkla hataların nedenleri ve koşulları hakkında ayrıntılı bilgiler vardır.Examine the event logs for the web server, which are likely to contain more detailed information about the causes and circumstances of the errors.

Bu kötü modelin belirtileri ve alınan bazı telemetri verileri Tek Parça Kalıcılık kötü modeline çok benzer olabilir.The symptoms of this antipattern and some of the telemetry obtained might be very similar to those of the Monolithic Persistence antipattern.

Nedeni belirlemenize yardımcı olması için aşağıdaki adımları gerçekleştirebilirsiniz:You can perform the following steps to help identify the cause:

  1. Yük testi, işlem izleme ya da izleme verileri yakalamaya yönelik başka yöntemlerle yavaş iş yükleri veya işlemleri tespit edin.Identify slow workloads or transactions by performing load-testing, process monitoring, or other methods of capturing instrumentation data.
  2. Sistem tarafından sergilenen tüm davranış kalıplarını gözlemleyin.Observe any behavioral patterns exhibited by the system. Saniye başına işlem veya kullanıcı sayısı açısından belirli bir sınır var mı?Are there particular limits in terms of transactions per second or volume of users?
  3. Yavaş iş yükü durumları ile davranış kalıpları arasında ilişki kurun.Correlate the instances of slow workloads with behavioral patterns.
  4. Kullanılan veri depolarını belirleyin.Identify the data stores being used. Her bir veri kaynağı için alt düzeyde telemetri çalıştırarak işlemlerin davranışını gözlemleyin.For each data source, run lower level telemetry to observe the behavior of operations.
  5. Bu veri kaynaklarına başvuran tüm yavaş çalışan sorguları belirleyin.Identify any slow-running queries that reference these data sources.
  6. Yavaş çalışan sorguların kaynağa özel analizini gerçekleştirin, verilerin nasıl kullanıldığını ve tüketildiğini saptayın.Perform a resource-specific analysis of the slow-running queries and ascertain how the data is used and consumed.

Aşağıdaki belirtilerin varlığını denetleyin:Look for any of these symptoms:

  • Aynı kaynağa veya veri deposuna gönderilen sık, büyük G/Ç istekleri.Frequent, large I/O requests made to the same resource or data store.
  • Paylaşılan bir kaynakta veya veri deposunda çekişme.Contention in a shared resource or data store.
  • Ağ üzerinden sık sık yüksek miktarda veri alan bir işlem.An operation that frequently receives large volumes of data over the network.
  • G/Ç’nin tamamlanması için ciddi bir süre bekleyen uygulama ve hizmetler.Applications and services spending significant time waiting for I/O to complete.

Örnek tanılamaExample diagnosis

Aşağıdaki bölümlerde, bu adımlar yukarıdaki örneklere uygulanmaktadır.The following sections apply these steps to the previous examples.

Yavaş iş yüklerini tespit etmeIdentify slow workloads

Aşağıdaki grafik, 400 adede kadar eşzamanlı kullanıcının daha önce gösterilen GetAllFieldsAsync yöntemini çalıştırmasının benzetimini yapan bir yük testinin performans sonuçlarını göstermektedir.This graph shows performance results from a load test that simulated up to 400 concurrent users running the GetAllFieldsAsync method shown earlier. Yük arttıkça aktarım hızı yavaşça azalır.Throughput diminishes slowly as the load increases. İş yükü arttıkça ortalama yanıt süresi artar.Average response time goes up as the workload increases.

GetAllFieldsAsync yönteminin yük testi sonuçları

AggregateOnClientAsync işlemine yönelik bir yük testi de benzer bir düzen gösterir.A load test for the AggregateOnClientAsync operation shows a similar pattern. İstek hacmi nispeten sabittir.The volume of requests is reasonably stable. İş yükü arttıkça ortalama yanıt süresi de artar, ancak bu artış önceki grafiğe göre daha yavaş gerçekleşir.The average response time increases with the workload, although more slowly than the previous graph.

AggregateOnClientAsync yönteminin yük testi sonuçları

Yavaş iş yükleri ile davranış kalıpları arasında ilişki kurmaCorrelate slow workloads with behavioral patterns

Düzenli olarak yüksek kullanım yaşanan dönemler ile performans düşmesi arasındaki herhangi bir ilişki sorunlu bir alana işaret ediyor olabilir.Any correlation between regular periods of high usage and slowing performance can indicate areas of concern. Yavaş çalıştığından şüphelenilen işlevlerin performans profilini yakından inceleyin. Bu profilin daha önce gerçekleştirilen yük testi ile eşleşip eşleşmediğini belirleyin.Closely examine the performance profile of functionality that is suspected to be slow running, to determine whether it matches the load testing performed earlier.

Adım bazlı kullanıcı yükleri kullanarak aynı işlevin yük testini yapın ve performansın ciddi ölçüde düştüğü veya tamamen sıfırlandığı noktayı bulun.Load test the same functionality using step-based user loads, to find the point where performance drops significantly or fails completely. Bu nokta gerçek dünyada beklediğiniz kullanım sınırları dahilindeyse işlevin nasıl uygulandığını inceleyin.If that point falls within the bounds of your expected real-world usage, examine how the functionality is implemented.

Yavaş bir işlem mutlaka bir sorun değildir. Sistem baskı altında olduğunda gerçekleştirilmiyorsa, zaman açısından kritik değilse ve başka önemli işlemlerin performansını olumsuz etkilemiyorsa bir sorun olarak görülmeyebilir.A slow operation is not necessarily a problem, if it is not being performed when the system is under stress, is not time critical, and does not negatively affect the performance of other important operations. Örneğin, aylık operasyonel istatistiklerin üretilmesi uzun süren bir işlem olabilir, ancak toplu bir işlem olarak yürütülüp düşük öncelikli bir iş olarak çalıştırılabilir.For example, generating monthly operational statistics might be a long-running operation, but it can probably be performed as a batch process and run as a low priority job. Öte yandan, müşterilerin ürün kataloğunu sorgulaması kritik bir iş işlemidir.On the other hand, customers querying the product catalog is a critical business operation. Yüksek kullanım dönemleri sırasında performansın nasıl değiştiğini görmek için bu kritik işlemler tarafından üretilen telemetri üzerinde odaklanın.Focus on the telemetry generated by these critical operations to see how the performance varies during periods of high usage.

Yavaş iş yüklerindeki veri kaynaklarını belirlemeIdentify data sources in slow workloads

Bir hizmetin veri alma şekli nedeniyle kötü performans gösterdiğinden şüpheleniyorsanız uygulamanın kullandığı depolar ile nasıl etkileştiğini araştırın.If you suspect that a service is performing poorly because of the way it retrieves data, investigate how the application interacts with the repositories it uses. Kötü performans gösterildiği sırada hangi kaynaklara erişildiğini görmek için canlı sistemi izleyin.Monitor the live system to see which sources are accessed during periods of poor performance.

Her bir veri kaynağı için sistemi izleyerek aşağıdakileri yakalayın:For each data source, instrument the system to capture the following:

  • Her bir veri deposuna erişim sıklığı.The frequency that each data store is accessed.
  • Veri deposunda giriş ve çıkış yapan veri hacmi.The volume of data entering and exiting the data store.
  • Bu işlemlerin süreleri, özellikle isteklerin gecikme süresi.The timing of these operations, especially the latency of requests.
  • Tipik bir yük altında her bir veri deposuna erişilirken oluşan hataların doğası ve oranı.The nature and rate of any errors that occur while accessing each data store under typical load.

Bu bilgileri, uygulama tarafından istemciye döndürülen veri hacmine göre karşılaştırın.Compare this information against the volume of data being returned by the application to the client. Veri deposu tarafından döndürülen veri hacminin istemciye döndürülen veri hacmine oranını izleyin.Track the ratio of the volume of data returned by the data store against the volume of data returned to the client. Büyük bir fark varsa uygulamanın gerek duymadığı veriler getirip getirmediğini araştırın.If there is any large disparity, investigate to determine whether the application is fetching data that it doesn't need.

Bu verileri yakalamak için canlı sistemi gözlemleyip her kullanıcı isteğinin yaşam döngüsünü izleyebilir veya bir dizi yapay iş yükü modelleyip bunları bir test sisteminde çalıştırabilirsiniz.You may be able to capture this data by observing the live system and tracing the lifecycle of each user request, or you can model a series of synthetic workloads and run them against a test system.

Aşağıdaki grafiklerde, GetAllFieldsAsync yönteminin yük testi sırasında New Relic APM kullanılarak yakalanan telemetri gösterilmektedir.The following graphs show telemetry captured using New Relic APM during a load test of the GetAllFieldsAsync method. Veritabanından ve ilgili HTTP yanıtlarından alınan veri hacimleri arasındaki farka dikkat edin.Note the difference between the volumes of data received from the database and the corresponding HTTP responses.

“GetAllFieldsAsync” yöntemi için telemetri

Her bir istek için veritabanı 80.503 bayt döndürdü, ancak istemciye giden yanıtta yalnızca veritabanı yanıtının %25’i civarında 19.855 bayt vardı.For each request, the database returned 80,503 bytes, but the response to the client only contained 19,855 bytes, about 25% of the size of the database response. İstemciye döndürülen verilerin boyutu biçime bağlı olarak değişebilir.The size of the data returned to the client can vary depending on the format. Bu yük testi için istemci JSON verileri istedi.For this load test, the client requested JSON data. XML kullanarak yapılan ayrı bir test (gösterilmemektedir), veritabanı yanıtının %44’ü kadar olan 35.655 bayt yanıt boyutu gösterdi.Separate testing using XML (not shown) had a response size of 35,655 bytes, or 44% of the size of the database response.

AggregateOnClientAsync yönteminin yük testi, daha aşırı sonuçlar göstermektedir.The load test for the AggregateOnClientAsync method shows more extreme results. Bu durumda her test, veritabanından 280 KB’ın üzerinde veri alan bir sorgu gerçekleştirdi, ancak JSON yanıtı sadece 14 bayt boyutundaydı.In this case, each test performed a query that retrieved over 280Kb of data from the database, but the JSON response was a mere 14 bytes. Bu büyük farkın nedeni yöntemin yüksek miktarda veriden toplu bir sonuç hesaplamasıdır.The wide disparity is because the method calculates an aggregated result from a large volume of data.

“AggregateOnClientAsync” yöntemi için telemetri

Yavaş sorguları belirleyin ve analiz edinIdentify and analyze slow queries

En fazla kaynak kullanan ve yürütülmesi en çok zaman alan veritabanı sorgularını bulun.Look for database queries that consume the most resources and take the most time to execute. Birçok veritabanı işleminin başlangıç ve tamamlanma zamanlarını bulmak için izleme ekleyebilirsiniz.You can add instrumentation to find the start and completion times for many database operations. Birçok veri deposu, sorguların nasıl gerçekleştirildiği ve iyileştirildiği hakkında ayrıntılı bilgi de sağlar.Many data stores also provide in-depth information on how queries are performed and optimized. Örneğin, Azure SQL Veritabanı yönetim portalındaki Sorgu Performansı bölmesi bir sorgu seçip ayrıntılı çalışma zamanı performans bilgilerini görüntülemenize olanak sağlar.For example, the Query Performance pane in the Azure SQL Database management portal lets you select a query and view detailed runtime performance information. GetAllFieldsAsync işlemi tarafından oluşturulan sorgu aşağıdadır:Here is the query generated by the GetAllFieldsAsync operation:

Windows Azure SQL Veritabanı yönetim portalındaki Sorgu Ayrıntıları bölmesi

Çözümü uygulama ve sonucu doğrulamaImplement the solution and verify the result

GetRequiredFieldsAsync yöntemini veritabanı tarafında bir SELECT deyimi kullanacak şekilde değiştirdikten sonra yük testi aşağıdaki sonuçları gösterdi.After changing the GetRequiredFieldsAsync method to use a SELECT statement on the database side, load testing showed the following results.

GetRequiredFieldsAsync yönteminin yük testi sonuçları

Bu yük testinde aynı dağıtım ve 400 eşzamanlı kullanıcıya göre benzetimi yapılmış aynı iş yükü kullanılmıştır.This load test used the same deployment and the same simulated workload of 400 concurrent users as before. Grafik çok daha düşük gecikme süresi göstermektedir.The graph shows much lower latency. Yanıt süresi, yükün artmasıyla birlikte yükselerek yaklaşık 1,3 saniyeye ulaşmaktadır. Önceki örnekte bu süre 4 saniyeydi.Response time rises with load to approximately 1.3 seconds, compared to 4 seconds in the previous case. Aktarım hızı da daha önceki saniyede 100 istek değerine göre daha yüksek olup saniyede 350 istektir.The throughput is also higher at 350 requests per second compared to 100 earlier. Veritabanından alınan veri hacmi artık HTTP yanıt iletilerinin boyutuna oldukça yakındır.The volume of data retrieved from the database now closely matches the size of the HTTP response messages.

“GetRequiredFieldsAsync” yöntemi için telemetri

AggregateOnDatabaseAsync yöntemi kullanarak yapılan yük testi aşağıdaki sonuçları oluşturur:Load testing using the AggregateOnDatabaseAsync method generates the following results:

AggregateOnDatabaseAsync yönteminin yük testi sonuçları

Ortalama yanıt süresi artık oldukça düşüktür.The average response time is now minimal. Bu durum esas olarak veritabanı G/Ç’sindeki büyük düşüşten kaynaklanan çok büyük bir performans artışıdır.This is an order of magnitude improvement in performance, caused primarily by the large reduction in I/O from the database.

AggregateOnDatabaseAsync yöntemi için ilgili telemetri aşağıdadır.Here is the corresponding telemetry for the AggregateOnDatabaseAsync method. Veritabanından alınan veri miktarı ciddi ölçüde azalarak işlem başına 280 KB yerine 53 bayt haline gelmiştir.The amount of data retrieved from the database was vastly reduced, from over 280Kb per transaction to 53 bytes. Bunun sonucunda dakika başına sürdürülen en yüksek istek sayısı yaklaşık 2.000’den 25.000’in üzerine çıkmıştır.As a result, the maximum sustained number of requests per minute was raised from around 2,000 to over 25,000.

“AggregateOnDatabaseAsync” yöntemi için telemetri