使用LINQ和SQL来过滤集合的区别

5

关于使用LINQ和SQL过滤集合的问题,我有一个非常普遍的疑问。假设您正在对数据库表运行相当复杂的筛选器。它运行了10,000次,每次筛选器可能都不同。从性能方面考虑,将整个数据库表集合加载到内存中并使用LINQ执行筛选器是否更好,还是应该让数据库使用SQL处理筛选器(因为这是它的用途)。有什么想法吗?

编辑:我应该更清楚地说明。假设我们正在谈论一个具有1000条记录和20列(包含int / string / date数据)的表。目前在我的应用程序中,我每半小时运行一次查询,将所有数据拉入集合(将该集合保存在应用程序缓存中),并在整个应用程序中过滤该缓存集合。我想知道这是否比执行大量往返到数据库服务器(它是Oracle fwiw)更糟糕。


我需要一些示例代码来了解复杂性,真正给您提供有效的视角。并且每次都是相同的集合吗? - code4life
2
我认为你自己已经回答了。 - Aristos
使用Linq2Sql或Linq2EF都是一样的。 - H H
4
"我有一个非常普遍的问题" - 不行。这太依赖于实际数据的大小、筛选条件的复杂性等。需要根据具体情况进行衡量。 - H H
我投票关闭。目前没有提供足够的信息。 - code4life
6个回答

2

编辑

这取决于您拥有的数据量。如果数据量很大,则使用SQL,如果较少,则使用LINQ。还要看从SQL服务器调用数据的频率,如果过于频繁,则最好将其加载到内存中,然后应用LINQ,否则使用SQL更好。

第一个答案

最好选择SQL而不是将其加载到内存中,然后应用LINQ过滤器。

一个原因是选择SQL而不是LINQ:

如果选择LINQ,当您获取10,000条记录时,它会加载到内存中并增加网络流量。

如果选择SQL,记录数量减少,因此利用的内存量较少,并且减少了网络流量。


什么?LINQ怎么可能会生成网络流量呢?如果只是一次性调用某个地方的静态数据(例如查找一个国家内所有邮政编码),而不需要每次都进行SQL查询,那该怎么办呢?如果只是一次性的数据读取,那么LINQ将会生成更少的流量。 - code4life
@PranayRana:不,OP说的是10,000次,而不是记录。 - code4life
@ImranRizvi - 啊,检查一下问题中的这行话:“最好将整个数据库表集合加载到内存中,并使用LINQ执行过滤器”,这就解释了我为什么写出了这个答案。 - Pranay Rana
@code4life - 是的,我误解了一点,但现在已经更新了答案...感谢您指出这一点... - Pranay Rana
尽管它还没有达到10K次,但我可以假设如果一个过滤器运行了10K次,那么它就在10K条记录上运行。 - Imran Rizvi
显示剩余6条评论

2

更新后:

它正在运行,假设运行了10,000次

我假设有一个包含1000条记录的表格

可以合理地假设1k条记录将很容易地适应内存。

然后在内存中运行10k个过滤器会更加经济实惠(LINQ)。
使用SQL将意味着加载10M条记录,这需要大量的I/O。


1

这取决于你的表有多大以及存储了什么类型的数据。

个人而言,如果您计划在同一请求中使用所有筛选器,则返回所有数据是最好的选择。

如果您使用ajax进行按需过滤,您可以每次从数据库重新加载数据(同时确保数据是最新的)。


0

我认为最好让SQL处理复杂的过滤和其他处理,但是你可能会问为什么。

主要原因是因为SQL Server具有您设置的索引信息,并使用此索引快速访问数据。如果您在Linq上加载它们,则无法获得此索引信息以快速访问数据,并且您将浪费访问它们的时间。此外,每次编译linq都需要花费时间。

您可以进行简单的测试以自行查看这种不同之处。什么测试?创建一个带有一百个随机字符串的简单表,并使用该字符串对该字段进行索引。然后,在字符串字段上进行搜索,一种使用linq,另一种直接询问sql。

更新

我的第一想法是SQL保留索引并根据您的SQL快速访问搜索数据。

然后我认为linq也可以将此过滤器转换为sql,然后获取数据,然后执行操作等...

现在我认为实际原因取决于您执行的操作。 直接运行SQL更快但原因取决于您实际设置的linq

如果您尝试将所有数据加载到内存中,然后使用linq进行操作,那么您会因为SQL索引速度变慢,同时还会浪费大量内存和时间将数据从SQL移动到内存中。

如果您使用linq获取数据,并且不需要进行其他搜索,则会浪费大量内存来移动所有这些数据,并且会损失内存。


0

这可能会引起一些关于数据库角色的争议!我曾经遇到过这个确切的问题,涉及相对复杂的过滤(例如,“在X国家,价格为y且具有z关键字”),而且速度非常慢。再加上,由于它是第三方数据库,我不被允许更改数据库结构。

我交换了所有逻辑,使得数据库仅返回结果(我每小时缓存一次),并在内存中进行过滤 - 当我这样做时,我看到了巨大的性能提升。


-1

这取决于您正在过滤的数据量。

您说过滤器运行了10K次,但每次可能都不同。在这种情况下,如果数据库中没有太多数据,您可以将其加载到服务器变量中。

如果数据库中有数十万条记录,则不应该这样做,也许您可以在数据库上创建索引和预编译程序以更快地获取数据。

您可以在其中实现缓存外观,以帮助您在第一次请求时将数据存储在服务器端,并根据您的要求进行更新。(您可以编写缓存以仅填充变量,前提是数据具有记录限制)。

您可以通过运行一些测试查询和观察来计算从数据库获取数据所需的时间。同时,您可以观察存储在内存中的数据的响应时间,并计算差异并根据此进行决策。

还有许多其他技巧,但基本线是

您必须观察并决定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接