C# Linq查询列表中的哪个位置,性能最好?
我有一个简单的linq查询,它从数据库中获取产品的slugC# Linq查询列表中的哪个位置,性能最好?,c#,linq,entity-framework,C#,Linq,Entity Framework,我有一个简单的linq查询,它从数据库中获取产品的slug var query = from url in urlTable where url.ProductId == productId && url.EntityName == entityName && url.IsActive orderby url.Id descending sele
var query = from url in urlTable
where url.ProductId == productId &&
url.EntityName == entityName &&
url.IsActive
orderby url.Id descending
select url.Slug
我正在尝试优化它,因为它是为每个产品运行的,在分类页面上,它是产品数量的x倍
var query = from url in urlTable
where productList.Contains(url.ProductId) &&
url.IsActive
orderby url.Id descending
select new { ProductId, Slug }
我可以这样做(如果我没有弄错的话),发送一个产品列表并进行新的查询
var query = from url in urlTable
where productList.Contains(url.ProductId) &&
url.EntityName == entityName &&
url.IsActive
orderby url.Id descending
select url.Slug
但是我在某个地方读到过,Contains的性能很差。还有别的办法吗?从性能角度看,最佳方法是什么
但是我在某个地方读到过,Contains的性能很差
我相信你把它和string.Contains
混在一起了,这在大型数据集上确实是个坏主意,因为它根本不能使用任何索引
无论如何,你为什么要猜测性能?你应该分析一下,看看什么对你自己更好。另外,请查看每个查询生成的SQL以及它们各自的查询计划
现在,有了这一点,第二个查询就更好了,因为它在一个查询中尽可能多地获取数据,从而消除了大量开销。如果您只查询了两三次,这一点就不太明显了,但一旦您进入(比如100次),您就有麻烦了。除了在客户机-服务器通信方面更好之外,在服务器上也更好,因为它可以非常有效地使用索引,而不是一个接一个地查找X项。请注意,对于通常没有对数访问时间的主键,这可能可以忽略不计。第二个选项更好。我会将
产品id
添加到结果中,以便您可以区分不同的产品
var query = from url in urlTable
where productList.Contains(url.ProductId) &&
url.IsActive
orderby url.Id descending
select new { ProductId, Slug }
请注意,您的产品id列表在(@p1、@p2、@p3)中转换为sql参数,并且每个sql查询有最大数量的sql参数。我认为极限大约是2000个参数。因此,如果您要查询2000多个产品,此解决方案将不起作用
var query = from productId in productList
join url in urlTable on productId equals url.ProductId
where url.IsActive
orderby url.Id descending
select url.Slug;
我相信这个查询会有更好的性能。我认为查询1是对的,你不能再优化了。在ProductId
上放置一个索引,在你真正需要的列上包含一个include,并在查询中只选择那些特定的列。另外,什么是productList
?你能用join吗?另一种方法是将这些段塞缓存在字典中。排序可能是一个性能问题。当您不使用id时是否需要该顺序?如果您阅读上述问题,您会发现包含的内容确实存在问题(可能仅限于包含数千个元素的大型列表,甚至仅包含10000个元素),并且已在EF 6中修复。祝您好运。这会引发运行时异常,因为您正在将内存中的列表与sql表联接,或者EF会在内存中提取完整的sql表,并将其联接到内存中,这是低效的。当然,这是假设urlTable是sql表,productList是内存中的列表。OP对此并不明确,但这是我从问题中得到的。当然,但没有理由相信产品驻留在DB之外,而urlTable
productList
可能只是对产品表的查询:productTable.Select(product=>product.ID)
…问题状态为“发送产品列表并执行新查询”,我将其解释为内存中的产品列表。但是你当然可能是对的。听起来,当访问一个类别时,他会查询该类别下的产品——如果是这样,连接将具有最好的性能(假设数据库中确实存在索引,并且productList
只是对数据库的查询)。由于使用EF,这会导致“linq to实体中仅支持无参数构造函数和初始值设定项”。