如何初始化我的实体框架查询以加快它们的速度?

Myk*_*oft 5 c# entity-framework-4 asp.net-mvc-4

我有一个登录页面,执行一个非常简单的EF查询来确定用户是否有效.在第一次运行时,此查询大约需要6秒才能运行.在后续运行中,它需要不到一秒钟.

我看过一篇谈论使用Application Auto-Start的文章,我的问题是这样的:有没有办法触发这个查询,无需实际调用查询就会导致任何缓存需求,或者我是否有必要用一组虚拟参数调用查询?

编辑:当我说六秒钟时,我指的是获取查询所需的时间.代码看起来像这样(注意,在这种情况下,contactID是一个可以为null的int并设置为null):

return from contact in _context.Contacts 
             where contact.District == Environment.District &&
             contact.ContactId == (contactID ?? contact.ContactId)
             select contact;
Run Code Online (Sandbox Code Playgroud)

这是一个SqlServer 2008,我运行一个分析器来检查SQL,它返回的持续时间是41ms,最终执行的查询.6或7秒延迟发生在查询甚至到达SQL之前.我现在正试图瞥见它是否可以给我更多关于可能同时发生的其他事情的细节.

Sla*_*uma 3

这听起来确实很像所谓的“冷查询”。冷查询的主要性能瓶颈是“视图生成”,它在应用程序的每个 AppDomain 中执行一次。通常,效果是您的第一个查询(无论哪个查询)很慢,而后续查询很快。

它不一定是一个可能很慢的查询。如果您在应用程序中使用 EF 执行的第一个操作是插入,那么速度会很慢。或者甚至Attach根本不接触数据库也会很慢。(顺便说一下,这是一个很好的简单测试用例:将一个添加context.Users.Attach(new User())到应用程序启动中,并在调试器中观察通过该行需要多长时间。)

在所有情况下,时间都消耗在内存中构建内部数据结构 - 本地查询“视图”(它们与数据库表视图无关) - 每个 AppDomain 发生一次。

此处更详细地描述了视图生成,您还可以在此处找到如何在构建过程中和部署之前“预生成”这些视图的资源。(注意:每次更改模型并重新部署应用程序时,您都必须更新这些预先生成的内容。)

另一种方法是定期触发加载 Web 应用程序(通过某个进程,例如访问网站)。在应用程序启动时,您将运行任何虚拟查询或Attach上面的内容,或者手动调用 EF 初始化:

using (var context = new MyContext())
{
    context.Database.Initialize(false);
}
Run Code Online (Sandbox Code Playgroud)

编辑

我忘记了最后一个解决方案。忽略这 6 或 7 秒即可。如果您的站点很出名并且具有合理的流量,那么这样的冷查询就不太可能发生,因为 IIS 工作进程很少会关闭 AppDomain。偶尔在夜间访问该网站(之前发生过此类关闭)的用户可能太累了,甚至没有注意到延迟。