繁体   English   中英

C#LINQ-SQL帮助-查询超过10,000个项目的数据库

[英]C# LINQ-SQL Help - Querying DB over 10,000 items

目前,我遇到了LINQ-> SQL速度问题。 我正在尝试检索10,000多种产品-这很好,因为将这些清单的代码,名称,描述和ID检索到列表的速度约为2秒。

然后,我的主要问题是尝试遍历这10,000个项目以计算库存数量(基于数据库表中匹配的库存项目(行)数)。 当然,要进行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();
    }

您应该使用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. 也许您应该考虑使用数据库视图来生成此数据,因为GetTotalStockCount方法无法转换为SQL查询以加快速度。 当然,这取决于GetTotalStockCount方法的复杂性。

  2. 在第一个查询中,从Products,StockItem和WarehouseLocation获取记录,然后将它们按Products分组以获得总计计数

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

因此,首先从数据库中获取计数并将其保存在列表中,然后在函数GetTotalStockCount中使用该列表。

问题在于,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可能会有所不同,具体取决于您的数据库的结构,但这是我想象的从您当前查询中看到的样子。

您可以尝试使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM