如何减少加载时间

时间:2019-07-16 07:06:45

标签: performance asp.net-core azure-cosmosdb

我正在更新类别中的产品,但是我的查询加载时间为4.32s。但是cosmos db可以读取。有什么办法可以减少时间?请给我建议任何想法。

第一次加载大约需要5秒,然后需要3-4.5秒。有什么办法可以解决这个问题?

我的存储库类代码:

public async Task<Catalog> UpdateProductInMainCategory(Guid productid, Product productData)
{
    var feedOptions = new FeedOptions
     {
         MaxItemCount = -1,
         EnableCrossPartitionQuery = true
     };

    var query =
        $"SELECT catalog.id,catalog.VendorName,catalog.Industy,product1 FROM catalog join industry in catalog.Industy join category in industry.Category join product1 in category.Product join Subcategory in category.Subcategory join product in Subcategory.Product where product1.Id ='" + productid + "'";

    var catlog = _cosmosClient.CreateDocumentQuery<Catalog>(UriFactory.CreateDocumentCollectionUri(
    _azureCosmosDbOptions.Value.DatabaseId, "catalog"), query, feedOptions).AsEnumerable().FirstOrDefault();

    Console.WriteLine("i am kajas");

    if (catlog != null)
    {
        foreach (var item in catlog.Industy)
        {
            foreach (var cat in item.Category)
            {
                Product product = cat.Product.FirstOrDefault(p => p.Id == productid);
                if (product != null)
                {
                    product.Name = productData.Name == null ? product.Name : productData.Name;
                    product.Addons = productData.Addons == null ? product.Addons : productData.Addons;
                    product.CurrentQuantity = 
                    break;
                }

            }
            break;
        }
    }
    var requestOptions = new RequestOptions
      {
          PartitionKey = new Microsoft.Azure.Documents.PartitionKey(catlog.Id.ToString())
      };

    var orderDocument = await _cosmosClient.ReplaceDocumentAsync(
         UriFactory.CreateDocumentUri(
             _azureCosmosDbOptions.Value.DatabaseId, "catalog", catlog.Id.ToString()), catlog, requestOptions);

    return (Catalog)((dynamic)catlog);
}

1 个答案:

答案 0 :(得分:1)

您还将MaxItemCount设置为-1,并且正在使用AsEnumerable().FirstOrDefault()。这意味着您将强制系统在单个页面中返回所有内容。但是,不建议这样做。最重要的是,我可以看到您没有使用ExecuteNextAsync方法。

重写代码应如下所示:

public async Task<Catalog> UpdateProductInMainCategory(Guid productid, Product productData)
{
    var feedOptions =
     new FeedOptions
     {
         MaxItemCount = 100,
         PartitionKey = new PartitionKey(productid.ToString())
     };

    var query =
        $"SELECT catalog.id,catalog.VendorName,catalog.Industy,product1 FROM catalog join industry in catalog.Industy join category in industry.Category join product1 in category.Product join Subcategory in category.Subcategory join product in Subcategory.Product where product1.Id ='" + productid + "'";

    var catlogQuery = _cosmosClient.CreateDocumentQuery<Catalog>(UriFactory.CreateDocumentCollectionUri(_azureCosmosDbOptions.Value.DatabaseId, "catalog"), query, feedOptions).AsDocumentQuery();

    Catalog catalog = null;

    while(catlogQuery.HasMoreResults)
    {
        var result = await catlogQuery.ExecuteNextAsync();
        if(result.Any())
        {
            catalog = result;
            break;
        }
    }

    Console.WriteLine("i am kajas");

    if (catlog != null)
    {
        foreach (var item in catlog.Industy)
        {
            foreach (var cat in item.Category)
            {
                Product product = cat.Product.FirstOrDefault(p => p.Id == productid);
                if (product != null)
                {
                    product.Name = productData.Name == null ? product.Name : productData.Name;
                    product.Addons = productData.Addons == null ? product.Addons : productData.Addons;
                    product.CurrentQuantity = 
                    break;
                }

            }
            break;
        }
    }
    var requestOptions =
      new RequestOptions
      {
          PartitionKey = new Microsoft.Azure.Documents.PartitionKey(catlog.Id.ToString())
      };

    var orderDocument = await _cosmosClient.ReplaceDocumentAsync(
         UriFactory.CreateDocumentUri(
             _azureCosmosDbOptions.Value.DatabaseId, "catalog", catlog.Id.ToString()), catlog, requestOptions);



    return (Catalog)((dynamic)catlog);
}

请注意,现在它将通过正确的分页过程,并且退出速度更快,因为它不会锁定正在查询的线程,并且在while循环中有第一个匹配项时也会返回。

顺便提一句,使用Cosmonaut似乎可以使您的代码受益。它提供了许多开箱即用的功能。相同的查询如下所示:

var query =
        $"SELECT catalog.id,catalog.VendorName,catalog.Industy,product1 FROM catalog join industry in catalog.Industy join category in industry.Category join product1 in category.Product join Subcategory in category.Subcategory join product in Subcategory.Product where product1.Id ='" + productid + "'";

var catalog = await _catalogStore.Query(query).FirstOrDefaultAsync();

完全公开,我是宇航员的创造者。