【问题标题】:How do I make a Linq to SQL query faster that includes multiple predicate criteria?如何使包含多个谓词条件的 Linq to SQL 查询更快?
【发布时间】:2016-05-01 23:34:30
【问题描述】:

当我从代码中执行此查询时,它的执行速度比从 SQL Server Management Studio 中执行等效 SQL 时慢 3 倍

代码

var myDataContext = new AccessMyDatabaseDataContext();
            myDataContext.ObjectTrackingEnabled = false;
var schedule = (from s in myDataContext.MyTable
                            where s.Date >= StartDate
                            && s.Date <= EndDate
                            && s.Name == "MySchedule"
                            && (s.Status.Equals("LIVE") || s.SomeOtherField.Equals("MyString"))
                            select s)
                            .ToList();

我有可变数量的预期记录,因此我无法分配直接数量的预期记录。我认为额外时间的原因是Linq2sql只要找到记录就会执行select top 1语句。

有人知道解决这个问题的方法吗?

编辑

最后,我比 Linq2Sql 更多。对不起!

我使用(几乎)相同语法(上图)的 3 个表,在 foreach 循环中为我的业务对象分配所需的值。问题是,其中一个访问查询没有 ToList-Command。 foreach 循环将我的 List-Objects 中的值与我的数据库中的值相结合。

一个尴尬的初学者错误。再次抱歉,感谢您的帮助!!!

【问题讨论】:

  • 我经常将存储过程用于复杂的 SQL。性能提升是值得的。问题是myDataContext 变得过时了。将代码包装在using var myDataContext = new AccessMyDatabaseDataContext(){}
  • 向我们展示您在 SQL Server Management Studio 中运行的等效 SQL,以及您对该表的索引和该表的结构。
  • 您确定 Select top1 来自此查询,而不是来自您引用某些相关实体信息的列表内容的 foreach()。从这个查询的内容中,我会非常惊讶地看到 N select top 1 statements。
  • @PeterBill:我想我也必须走这条路。我用“using-wrap”试过了,但执行时间几乎一样......
  • @Pleun:在阅读了您的评论后,我再次对其进行了校对,我发现,我有一种不同的方式以另一种方式进行访问。事实上,我忘记了“ToList”- 方法,实际上它与语句一起运行到了 foreach 中。周末模式 - 真丢脸 -.- 我现在让它更易于重复使用。

标签: c# sql-server performance linq-to-sql


【解决方案1】:

DbContext 的生命周期在MSDNSO 上进行了描述。当我替换我的类变量 DbContext 时,我注意到了一个很大的改进(重复从 2 个连接表中获取所有数据的测试循环从 7 分钟减少到 4.3 秒)。

我相信任何复杂的 SQL 在存储过程中都会更好。 RDBMS 只需优化一次。你只返回你想要的行。有许多资源可帮助优化 SQL Server 中的查询,例如 https://msdn.microsoft.com/en-us/library/ff650689.aspx

经常被忽视的是 SQL Server Management Studio(于 2005 年推出)的数据库报告功能。在对象资源管理器中右键单击数据库名称并选择报告 -> 标准报告 -> 任何报告。试验报告。我找到了这个网站http://www.sqlshack.com/sql-server-management-studio-performance-reports/

【讨论】:

    【解决方案2】:

    始终检查生成的 SQL 查询,方法是注销 SQL 或启动 SQL 分析器。我的猜测是生成的 SQL 不会差。您可能会浪费时间的原因:

    1. 由于对象物化,ERM 框架总是有点慢。如果您不需要所有字段,请引入 .Select() 子句以仅选择您实际需要的部分。通常,序列化为非实体类型,例如转换成匿名类型,速度更快。

    2. 表达式树的解析会消耗相当长的时间。 Linq2Sql 中有一个编译查询的概念,它只在第一次解析表达式树。你启用了这个吗?有许多关于如何做到这一点的教程。

    话虽如此,对于 ERM 框架来说,3 倍并不是非典型的。根据您的需要,您可能会考虑 EntityFrmaework 是否更快。或者,有一些超轻量级 ERM 框架针对查询性能进行了优化,但不太适合用于管理对象。

    作为最后一种选择,EntityFramework(可能还有 Linq2Sql)允许您获取直接的 SQL 字符串。您可以使用此字符串加载 DataTable。

    【讨论】:

    • 感谢您的想法!我已经完成了 linq2sql 的大部分实现。它是一个原型,我想有时间学习 EF。我没有太多时间来提供这个解决方案,现在我只尝试提高 db-access 的性能。我已阅读有关 CompiledQueries 的信息并且我明白,对于我的 UseCase 这不会是一个更快的解决方案...
    • 谁能告诉我为什么这个答案被降级了?!
    • 我无法评价,所以我不是原因;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    相关资源
    最近更新 更多