【发布时间】:2011-03-14 17:35:09
【问题描述】:
像许多人一样,我试图从我的应用中获得最佳性能,同时尽可能保持代码的简单和可读性。我正在使用 Linq-to-SQL,并且我真的试图让我的数据层尽可能地具有声明性。
我假设 SQL 调用是最昂贵的操作。因此,我尽量减少它们的数量,但尽量避免难以优化的疯狂复杂查询。
举个例子:我在我的 DataContext 中使用DataLoadOptions——它的目标是通过预加载相关实体来最小化查询的数量。 (也就是急切加载与延迟加载。)
问题:Linq 使用连接来实现目标。与所有事情一样,这是一种权衡。我得到的查询越来越少,但那些加入的查询更加复杂和昂贵。进入 SQL Profiler 可以清楚地说明这一点。
所以,我想在 Linq 中提供一个选项来在没有连接的情况下预加载。这可能吗?下面是它的样子:
我有一个Persons 表、一个Items 表和一个PersonItems 表来提供多对多关系。在加载 Persons 集合时,我希望他们的所有 PersonItems 和 Items 也都急切地加载。
Linq 当前使用一个包含两个连接的大型查询来执行此操作。我宁愿它做的是三个非连接查询:一个用于 Persons,一个用于与这些 Persons 相关的所有 PersonItems,一个用于与这些 PersonItems 相关的所有 Items。然后 Linq 会自动将它们排列到相关实体中。
其中的每一个都是快速的、firehose 类型的查询。从长远来看,它可以实现可预测的网络规模性能。
见过吗?
【问题讨论】:
-
对于答案来说还不够好,但我想我只是想知道为什么你似乎对加入有一种自动的负面反应,而没有分析它们是否真的在性能上更差。另一方面,有人可能会指出,在一个连接时执行多个查询——使用适当的外键——可以做得同样好,或者更好。最后,代码也可能会变得更简单。
-
很公平,尽管我将复杂性视为性能的代表。它目前表现良好,但似乎连接在费用方面必须呈指数级 - 每个连接乘以行 x 行。这也是性能和规模之间的区别。规模是指性能是可预测的,即线性的。