2010-01-05 51 views
3

我们最近开始使用complied查询来提高我们的Linq to SQL设置的性能。有几个查询总是需要几秒钟的时间才能在第一次运行时在第二次运行中第一次运行。这似乎是因为编译实际上并没有发生,直到第一次打电话。为什么我的编译linq查询第一次放缓?

是否有一种简单的方法可以在编译程序期间或至少在启动过程中强制执行此编译?

编辑: 所以从我看到的看来,它看起来像linq查询是绝对不会编译,直到进行调用。现在我正在写我这样的查询:

static readonly Func<DataContext, int, IQueryable<Item>> getByPLUComp = 
    CompiledQuery.Compile<DataContext, int, IQueryable<Item>>((db, PLU) => 
      from i in db.Items 
      where i.IntPLU == PLU && i.Terminated == null 
      select i); 

我有一堆这些静态只读Funcs漂浮。有没有一种简单的方法,我可以让我的程序运行并在启动时将它们初始化,以便在那里发生成本,而不是在正常使用期间发生?

编辑2: 我放弃这个问题之前的最后一次尝试。为了解决这个问题,我刚刚在程序的初始化过程中添加了对编译查询的调用。例如:

public void Initialize() 
{ 
    DataContext db = new DataContext(); 
    getByPLUComp(db, 0); 
} 

是否有更优雅的方式来强制编译,而不仅仅是运行查询并丢弃结果?

+0

你确定它不只是因为你让首次到数据库的连接?或者说,延迟不是来自sql服务器端,这是一个缓存问题? – cyberconte 2010-01-05 20:15:52

+0

有问题的查询不是应用程序运行的第一个查询。问题也是一致的。每次程序运行时都会发生这种情况。 – Mykroft 2010-01-05 20:21:23

+2

你可能会发现这一系列的博客文章很有趣:http://blogs.msdn.com/ricom/archive/2007/06/22/dlinq-linq-to-sql-performance-part-1.aspx - 对编译查询进行编译直到第一次使用才会被编译。其中一个帖子应该阐明为什么这项政策存在。 – jalf 2010-01-05 20:46:21

回答

0

服务器需要是第一次执行时的查询计划,然后使用缓存计划进行后续执行。

1

在执行SQL数据库将被缓存两两件事:

  1. 执行计划
  2. 数据

执行计划将保留在缓存中针对相同的查询后续调用直到它“过期”。但是,由于数据保存在内存中,数据缓存通常会产生最大的性能差异,所以后续调用不需要访问磁盘即可获取。

+0

这是非常少量的数据,即使数据发生变化,通话时间也不会突然增加。那么我的问题在SQL Server端呢? – Mykroft 2010-01-05 20:23:01

+0

我会这么认为,这是查询实际执行的地方。我将运行SQL Profiler,监视进入的调用。查询可能效率低下 - 我将检查SQL实际正在执行的情况,检查执行计划。如果它真的效率低下/缺乏索引等,那么这就是为什么即使是少量返回的数据,第一次运行速度明显较慢的原因。 – AdaTheDev 2010-01-05 20:31:46

+0

我的印象是,这些调用花了这么长时间的原因是由于将linq转换为sql而不是sql本身的执行所花费的时间。 – Mykroft 2010-01-05 20:36:30

0

Sql数据第一次将提高其他运行。 。 。您可以制作脚本,通过调用运行,以便兑现。您可以将其添加到安装过程中。 。 。 。这可能有效。

您可以创建一个表来更新所需的信息。这种方式当你需要的信息可读。 (如果将数据放在一起需要很多处理)