C#LINQ-SQL帮助 - 查询DB超过10,000个项目

时间:2015-04-10 10:27:53

标签: c# mysql .net linq

我遇到LINQ问题 - > SQL速度此刻。我正在尝试检索超过10,000种产品 - 这很好,因为检索这些列表的代码,名称,描述,ID的速度大约是2秒。

我的主要问题是尝试迭代这10,000个项目以计算库存数量(基于与db表中匹配的库存项目(行)数量)。这当然会超过10,000次调用SQL来解决这个问题 - 这需要花费很多时间。我需要这个计算,然后我的过滤器只基于具有特定数量的过滤器。

 IEnumerable<Product> filteredRecords = warehousing.GetProducts(wID);  // Takes under 2 seconds for 10k records

                var data = filteredRecords
                                .Select(p => new
                                {
                                    ID = p.ProductID,
                                    ProductName = p.Product.Name,
                                    ProductCode = p.Product.Code,                                        
                                    StockLevel = stock.GetTotalStockCount(p.ProductID, p.WarehouseID.Value)
                                }).OrderBy(l => l.StockLevel).ToArray();

我是否应该尝试恢复原生查询以略微提高速度,或者我应该选择后台流程来定期计算库存计数并将它们存储到单独的表中?

我不确定在这种情况下最佳做法/做法是什么?

修改 正是这个计算增加了惩罚。 包括GetTotalStockCount方法:

        public int GetTotalStockCount(Int32? productID = null, Int32? warehouseID = null)
    {

        var query = from stockItem in _unitOfWork.StockItemRepository.Get(w => w.ProductID == productID).Select(s => s.LocationID)
                    join warehouseLocation in _unitOfWork.WarehouseLocationRepository.Get(w => w.WarehouseID == warehouseID && w.Type == WarehouseLocationType.Stock).Select(s => s.ID) on stockItem.Value equals warehouseLocation
                    select new { stockItem.Value };

        return query.Count();
    }

5 个答案:

答案 0 :(得分:0)

您应该使用StockCount过滤数据,并且在真正需要之前不应使用ToArray

试试这个:

 IEnumerable<Product> filteredRecords = warehousing.GetProducts(wID);  // Takes under 2 seconds for 10k records

var data = filteredRecords
    .Select(p => new
    {
        ID = p.ProductID,
        ProductName = p.Product.Name,
        ProductCode = p.Product.Code,                                        
        StockLevel = stock.GetTotalStockCount(p.ProductID, p.WarehouseID.Value)
    }).Where(l => l.StockLevel > NEEDED_AMOUNT);

并考虑在数据库层上移动GetTotalStockCount方法来过滤您的数据。

答案 1 :(得分:0)

您有两种选择:

  1. 可能你应该考虑使用view on database来生成这个数据,因为GetTotalStockCount方法无法转换为SQL查询来加速。当然,这取决于GetTotalStockCount方法的复杂性。

  2. 在第一个查询中,从Products,StockItem和WarehouseLocation获取记录,然后按产品对它们进行分组以计算聚合

答案 2 :(得分:0)

您需要更改方法GetTotalStockCount以从内存列表而不是数据库中获取计数。

因此,首先从列表中的DB中获取并保存计数,并在函数GetTotalStockCount中使用该列表。

答案 3 :(得分:0)

问题是GetTotalStockCount方法是在一个单独的,每个记录一次点击数据库。我不确定我的数据库结构是否正确,但你可以试试这个:

.Select(p => new
    {
        ID = p.ProductID,
        ProductName = p.Product.Name,
        ProductCode = p.Product.Code,                                        
        StockLevel = p.StockItem.WarehouseLocation.Where(w => w.WarehouseID == p.WarehouseID.Value).Count()
    }).OrderBy(l => l.StockLevel).ToArray();

这将计算sql查询中的库存水平项,并表示只有一个数据库命中。

注意:.StockITem.WarehouseLocation可能会根据db的结构而改变,但这就是我想象的当前查询的结果。

答案 4 :(得分:0)

你可以试试TSQL

select p.ProductID, p.Product.Name, p.Product.Code, count(*)    
  from StockItemRepository p    
  join WarehouseLocationRepository w
    on p.ProductID = w.WarehouseID.Value    
   and w.Type == WarehouseLocationType.Stock   
 group by p.ProductID, p.Product.Name,  p.Product.Code