【问题标题】:How to precompile sql queries in EF Code-First?如何在 EF Code-First 中预编译 sql 查询?
【发布时间】:2015-11-23 17:24:51
【问题描述】:

我正在使用 ASP.Net4.5.1 和 EF6.0 代码优先方法。

我意识到查询需要相当长的时间来执行。我使用 EF Profiler 来检查查询并微调查询。

我用谷歌搜索并开始了解编译 Linq。

这些是我得到的链接。

但没有一个能解决我的担忧。

假设我有以下查询。

public IEnumerable<Student> GetStudents()
{
  using(DbContext db = new DbContext()
  {
  IQueryable<Student> query = (from c in db.Students
                                where c.Hobby== "Hockey"
                                select c);
  IEnumerable<Student> students= query.toList<Student>();

  return students;
  }
 }

现在如何缓存查询计划或编译此 Linq 以提高性能?

这里还要问一个问题,EF 比原生 SQL 慢吗?

我更喜欢使用EF/ORM,是不是正确的选择?

【问题讨论】:

  • 我们是在谈论第一次查询执行(通常包括视图生成时间),还是一般的查询执行?
  • @tschmit007 查询执行
  • 此代码来自您的应用还是与您的应用无关的示例代码?根据您的一些回复,您似乎没有发布真正的代码。如果是这样的话,就很难提供帮助了。

标签: c# asp.net asp.net-mvc entity-framework sql-server-2008


【解决方案1】:

是的,EF 比 SQL 慢。 any ORM 也是如此。 ORM 必须能够将基于代码的“查询”转换为真正的 SQL 查询,然后它必须使用结果来实例化对象图。但是,这些通常是您想要 ORM 的东西。手动执行此类操作会更困难且更容易出错。

您是否使用 ORM 完全取决于您的应用程序的需求。通常,是的,推荐使用 ORM,但如果您需要极高的性能,则可能需要使用纯 SQL。 ORM 的个人表现也大相径庭。众所周知,EF 是一个特别慢的 ORM。它是最容易使用和使用的,但如果性能是一个问题,你最好使用像 Dapper 这样的东西。您还可以混合和匹配 ORM 和 SQL 用法。将EF用于标准CRUD,然后使用存储过程进行复杂查询,一点也不异常。

话虽如此,您的查询非常基本。如果您遇到类似的性能问题,可能是您的 SQL Server 实例没有获得足够的资源来使用,您的网络速度非常慢,或者该表中有大量数据并且您没有正确利用索引.

最后一点,文本搜索通常是使用 SQL 执行的最慢的搜索之一。如果您打算查询特定的基于文本的列,例如Hobby,则应在其上添加索引。您可以在数据库中手动执行此操作,也可以使用属性上的 [Index] 数据注释。请记住,只能索引固定长度的基于文本的列。默认情况下,EF 将生成字符串属性为NVARCHAR(MAX)。如果要在列上使用索引,则需要将 [Index][MaxLength(N)] 结合使用。

【讨论】:

  • 谢谢.. :) 我添加了正确的唯一索引.. 你能在这里给我建议一件事吗.. 我的应用程序是关于在线预订你说我应该使用 EF 还是原生 SQL
  • 这不仅仅是应用程序的基本目的。您期望什么样的负载?它会被数百、数千或数百万人使用吗?您正在运行的查询有多复杂?还有一百万个其他问题可以问。我不期待实际的答案。我只是说,必须做出决定。此外,应将直接 SQL 视为最后的手段。在你走这条路之前,你应该在你的数据库和网络服务器上投入大量的 RAM 和处理核心。
  • 1k-2.5k 每天点击量..查询不是太复杂..现在根据你我应该使用 EF 还是原生 SQL
  • 不,不是真的,但你问的问题全都错了,更重要的是,你过早地优化。构建您的应用程序,不用担心它。当需要部署时,将其暂存并投入负载,然后且仅在必要时进行优化。构建一个可以完美运行的应用程序是不可能的。每种情况都是独一无二的,优化和规模总是在进行中。你从一个好的基础开始,然后从那里开始。这就是这些东西的工作原理。
【解决方案2】:

如果您想要更快的数据访问代码,您应该考虑使用 Pure ADO.NET 代码,该代码使用 SqlCommandSqlDataReaderExecuteReader 方法执行 SQL 查询。但是现在您需要编写一些额外的代码来创建SqlCommand,传递查询和参数并从SqlDataReader 中读取行。

您应该考虑一些小型 ORM,例如 Dapper。它比EF快得多。正如我上面提到的,您不需要编写太多代码。 Dapper 将执行您的查询并将结果集映射到您的 DTO。

使用 Dapper 的快速示例。

var con= new SqlConnection("YourConnectionStringGoesHere");
var posts = con.Query<Post>("SELECT ID,Name from Post");

Dapper 支持从多个表中读取数据 (JOIN) 并映射到具有导航属性的对象。

看看他们的表现数据

EF/NHibernate 将帮助您进行快速开发,因为使用它们的 API/方法与数据库进行对话很容易。但是你要为表现付费。

另外要记住的重要一点是优化您的 sql 查询。即使使用纯 ADO.NET,如果您的 sql 查询没有优化,您的性能也会很差。为您的表/列添加适当的索引也可能会有所帮助。

我不完全确定您的应用程序,但是您应该阅读有关缓存数据的内容,这样您的数据库就不会一直受到攻击。这通常会提高你的表现。

【讨论】:

  • @Shyju..非常感谢... :) 我的应用程序是在线预订系统.. 你能建议我使用 EF 还是原生 SQL?因为我们处于非常初始的阶段..我觉得这是决定它的正确阶段..仅供参考 性能是我首先关心的
  • 您始终可以将 Dapper/Pure ADO.NET 与 EF 混合使用。您应该能够自己确定项目的哪个部分需要最佳性能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多