Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq查询列表中的哪个位置,性能最好?_C#_Linq_Entity Framework - Fatal编程技术网

C# Linq查询列表中的哪个位置,性能最好?

C# 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

我有一个简单的linq查询,它从数据库中获取产品的slug

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实体中仅支持无参数构造函数和初始值设定项”。