如何初始化我的entity framework查询以加快它们的速度?

我有一个登录页面,执行一个非常简单的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; 

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

这听起来像是所谓的“冷查询”。 冷查询的主要性能botteneck是“View Generation”,每个应用程序的AppDomain执行一次。 通常情况下,您的第一个查询 – 无论哪个查询 – 都很慢,后续查询速度很快。

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

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

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

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

 using (var context = new MyContext()) { context.Database.Initialize(false); } 

编辑

我忘记了最后的解决方案。 只需忽略6或7秒。 如果您的站点出名并且流量合理,则不太可能发生冷查询,因为IIS工作进程很少会关闭AppDomain。 偶然的用户在夜间发生这样的关闭之前就已经发现该网站可能太累了甚至没有注意到延迟。