我有一个执行一个非常简单的EF查询,以确定用户是否是有效的登录页面。 在第一次运行该查询需要大约6秒运行。 在之后的运行需要不到一秒多。
我看着那个谈到使用的文章应用程序自动启动 ,我的问题是:有没有触发这个查询造成任何缓存需求,而不实际调用查询发生的方式,或者是我有必要,只是调用设置的参数的虚拟查询?
编辑:当我说6秒我指需要得到查询的时间。 代码看起来是这样的(注意在这种情况下使用ContactID是一个可空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是“生成视图”,这是每个应用程序的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。 谁打的网站时,这样的关停已经向右发生之前的晚上偶尔的用户可能是太累了,甚至没有注意到的延迟。