用40,000行加速linq查询

时间:2014-04-01 15:29:23

标签: c# linq optimization

在我的服务中,首先我生成40,000种可能的家庭和东道国组合,如此(clientLocations包含200条记录,所以200 x 200是40,000 ):

foreach (var homeLocation in clientLocations)
{
    foreach (var hostLocation in clientLocations)
    {
        allLocationCombinations.Add(new AirShipmentRate
        {
            HomeCountryId = homeLocation.CountryId,
            HomeCountry = homeLocation.CountryName,
            HostCountryId = hostLocation.CountryId,
            HostCountry = hostLocation.CountryName,
            HomeLocationId = homeLocation.LocationId,
            HomeLocation = homeLocation.LocationName,
            HostLocationId = hostLocation.LocationId,
            HostLocation = hostLocation.LocationName,
        });
    }
}

然后,我运行以下查询以查找上述位置的现有费率,但也包括清空丢失的费率;产生了40,000行的完整记录集。

var allLocationRates = (from l in allLocationCombinations
                        join r in Db.PaymentRates_AirShipment
                            on new { home = l.HomeLocationId, host = l.HostLocationId }
                            equals new { home = r.HomeLocationId, host = (Guid?)r.HostLocationId }
                        into matches
                        from rate in matches.DefaultIfEmpty(new PaymentRates_AirShipment
                        {
                            Id = Guid.NewGuid()
                        })
                        select new AirShipmentRate
                        {
                            Id = rate.Id,
                            HomeCountry = l.HomeCountry,
                            HomeCountryId = l.HomeCountryId,
                            HomeLocation = l.HomeLocation,
                            HomeLocationId = l.HomeLocationId,
                            HostCountry = l.HostCountry,
                            HostCountryId = l.HostCountryId,
                            HostLocation = l.HostLocation,
                            HostLocationId = l.HostLocationId,
                            AssigneeAirShipmentPlusInsurance = rate.AssigneeAirShipmentPlusInsurance,
                            DependentAirShipmentPlusInsurance = rate.DependentAirShipmentPlusInsurance,
                            SmallContainerPlusInsurance = rate.SmallContainerPlusInsurance,
                            LargeContainerPlusInsurance = rate.LargeContainerPlusInsurance,
                            CurrencyId = rate.RateCurrencyId
                        });

我尝试过使用.AsEnumerable().AsNoTracking(),这加快了速度。 以下代码可以减少几秒钟的查询:

var allLocationRates = (from l in allLocationCombinations.AsEnumerable()
                        join r in Db.PaymentRates_AirShipment.AsNoTracking()

但是,我想知道:我怎样才能加快速度呢?

修改:无法在linq中复制foreach功能。

allLocationCombinations = (from homeLocation in clientLocations
                            from hostLocation in clientLocations
                            select new AirShipmentRate
                            {
                                HomeCountryId = homeLocation.CountryId,
                                HomeCountry = homeLocation.CountryName,
                                HostCountryId = hostLocation.CountryId,
                                HostCountry = hostLocation.CountryName,
                                HomeLocationId = homeLocation.LocationId,
                                HomeLocation = homeLocation.LocationName,
                                HostLocationId = hostLocation.LocationId,
                                HostLocation = hostLocation.LocationName
                            });

我在from hostLocation in clientLocations上收到错误,上面写着“无法将IEnumerable类型转换为Generic.List。”

2 个答案:

答案 0 :(得分:3)

查询数据库的最快方法是使用数据库引擎本身的强大功能。

虽然Linq是一种非常棒的技术,但它仍然会从Linq查询中生成一个select语句,并对数据库运行此查询。

最好的办法是创建数据库视图或存储过程。

可以轻松地将视图和存储过程集成到Linq中。

材质视图(在MS SQL中)可以进一步加快执行速度,缺少索引是加速数据库查询的最有效工具。

答案 1 :(得分:2)

  

我怎样才能加快速度呢?

优化是 婊子

您的代码对我来说很好。确保在数据库架构上设置适当的索引。正如已经提到的:针对SQL运行你的Linq以更好地了解性能。


那么,但是如何提高性能呢?

您可能希望看一眼以下链接: 10 tips to improve LINQ to SQL Performance

对我来说,可能是列出的最重要的一点(在上面的链接中):

  • 仅检索您需要的记录数
  • 如果不是,请关闭数据上下文的ObjectTrackingEnabled属性 必要
  • 使用DataLoadOptions.AssociateWith
  • 将数据过滤到您需要的内容
  • 在需要时使用已编译的查询(请注意那个...)