会喜欢你对这一点的想法。
我在ASP.NET MVC应用程序中使用jQuery自动完成来从数据库中检索记录列表 - 我想知道是否有比我目前正在做的更好的方式 - 如下所示:
这是jQuery(我用自动填充调用了一个动作方法'GetRecordByName')
$('#tb_name').autocomplete({
source: 'Home/GetRecordByName',
minLength: 1, delay: 0,
select: function (event, ui) {
// do stuff
}
});
在后端,我在方法中使用Linq to Entities从数据库中获取结果:
public JsonResult GetRecordByName(string term)
{
var data = records
.Where(dr => dr.Key.StartsWith(term))
.Select(dr => new { dr, value = dr.Key })
.Take(5);
return Json(data, JsonRequestBehavior.AllowGet);
}
目前,它的运行速度有点慢(约1-2秒)。基本上,DB中有数万条记录,每次在文本框中键入字符时,应用程序都会访问数据库。我可以将它设置为2或3个字符,但它不会改变速度,也不需要那么多字符。
我对如何优化它有一个想法:在页面加载时,从数据库获取所有可能的结果并将其发送到客户端(通过隐藏的输入或javascript数据结构),并自动完成使用该客户端数据作为来源。我确信这会闪电般快,但对我来说似乎很奇怪 - 这样做有什么缺点吗?
还有其他方法可以实现更快的自动填充吗?
更新: 好吧,显然问题在于我构建EF调用的方式。关于'记录'的EF调用最终没有在sql查询中构造WHERE子句;它每次都得到整个表格,然后linq方法正在消除已经列举的大量数据 - 每次输入一个字母时都会发生这种情况 - 导致减速。卫生署!我将.Where方法移动到数据存储库层,在它过滤结果之后枚举它,并返回一个字典 - 现在似乎工作得很好。感谢你的帮助!我标记了最有帮助的答案,帮助我调查了这个问题。
就Flickr解决方案/将整套数据带到客户端而言,我仍然觉得这很奇怪/过度杀伤,但我确信这对于某些大型数据集是有保证的。对于其他事情,还会更多地关注OutputCache。
再次感谢!
答案 0 :(得分:6)
与任何优化一样,首先必须进行测试以找出瓶颈所在。否则你的努力将集中在错误的领域。例如,使用Firebug查看实际请求的持续时间。在MVC操作中使用秒表来查看实际数据检索需要多长时间(在查询结束时调用ToList
以确保它在方法中进行评估)。
在我们知道减速的位置之前,我们不可能给你一个非常好的优化建议,但这里有几个想法:
在页面加载时,从数据库获取所有可能的结果并将其发送到客户端(通过隐藏输入或javascript数据结构),并使用客户端数据作为源自动完成。我相信这会闪电般快,但对我来说似乎很奇怪 - 这样做有什么缺点吗?
是的,有缺点。您说数据库中有成千上万的可能结果:您怀疑数据库需要几秒钟才能从查询中返回一些结果。在初始页面加载的情况下将所有这些条目加载到页面中将对初始页面加载产生巨大的性能影响。这可能会使您的页面大小比需要的大10倍,这对于网络连接速度较慢的用户来说会有很大的不同。
答案 1 :(得分:2)
1)这实际上取决于您的使用情况和数据,但我建议使用[OutputCache]
。每次任何用户调用相同的控制器操作时,您都可以避免执行数据库查询。 Refer this for more details.。它只适用于每个用户,如果您在控制器操作级别使用缓存,它将为所有用户缓存一个。
2)看看这个问题的答案:How to improve performance of Jquery autocomplete
"This widget downloads a list of all of your contacts, in JavaScript, in under 200ms
(this is true even for members with 10,000+ contacts). In order to get this level of
performance, we had to completely rethink how we send data from the server to the client."
3)我见过有人使用Redis。它需要一些设置,但它是有效的。
答案 2 :(得分:1)
你提到的方式并不是一个坏主意 - 但是像StriplingWarrior提到的那样,它可能会影响你的页面加载。解决这个问题的方法是在页面加载上执行异步ajax调用,并在成功回调中绑定返回到自动填充的数据。
这意味着自动完成功能将不起作用,直到返回结果,但是有什么机会使用文本框并输入< 2/3秒?
答案 3 :(得分:0)
我不确定您的设置,但您可以采用的一个优化路径是使用redis将所有可搜索的参数存储为键/值对。只需设置任务即可保持更新。