【问题标题】:jQuery autocomplete - optimization questionjQuery自动完成 - 优化问题
【发布时间】:2011-05-12 15:09:06
【问题描述】:

会喜欢你对这个的想法。

我在 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 秒)。基本上,数据库中有数万条记录,每次您在文本框中键入一个字符时,应用程序都会访问数据库。我可以将它设置为 2 或 3 个字符,但它不会改变速度,我也不想需要那么多字符。

我对如何优化它有一个想法:在页面加载时,从数据库中获取所有可能的结果并将其发送到客户端(通过隐藏输入或 javascript 数据结构),并让自动完成功能将该客户端数据用作来源。我敢肯定这会快如闪电,但对我来说似乎很奇怪 - 这样做有什么缺点吗?

还有其他方法可以实现更快的自动完成吗?

更新: 好的,显然问题出在我构建 EF 调用的方式上。 EF 取消“记录”最终不是在 sql 查询中构造 WHERE 子句;它每次都获取整个表格,然后 linq 方法正在关闭已经枚举的大量数据 - 每次键入字母时都会发生这种情况 - 导致速度减慢。嗬!我将 .Where 方法移至数据存储层,它在 where 过滤结果后进行枚举,并返回 Dictionary - 现在似乎工作得很好。感谢你的帮助!我标记了对我调查问题最有帮助的答案。

就 Flickr 解决方案/将整组数据提供给客户端而言,我仍然觉得这很奇怪/矫枉过正,但我​​确信某些大型数据集是有保证的。还将更多地研究 OutputCache 的其他内容。

再次感谢!

【问题讨论】:

  • 忘了说,在后面使用了一个ILookup [private readonly ILookup records = Repository.GetDirectoryRecordsAll();]
  • 各位,非常感谢您的回复!我正在研究各种选项,并会让您知道最适合我的方案的解决方案

标签: jquery asp.net-mvc jquery-autocomplete


【解决方案1】:

与任何优化一样,首先您必须进行测试以找出瓶颈所在。否则你的努力将集中在错误的领域。例如,使用 Firebug 查看实际请求需要多长时间。在 MVC 操作中使用秒表来查看实际数据检索需要多长时间(在查询结束时调用 ToList 以确保它在方法内进行评估)。

在我们知道减速在哪里之前,不可能给你一个真正好的优化建议,但我想到了一些想法:

  • 使用 SQL Server Management Studio 分析 LINQ to Entities 生成的查询的执行路径。也许在文本列上添加某种索引会使数据库更快地返回结果?
  • Windows 中的 DNS 问题通常会导致非 IE 浏览器在开发环境中运行缓慢。如果这在 IE 中运行很快,但在 Firefox 中不行,您可能只需要调整您的 Hosts 文件。

在页面加载时,从数据库中获取所有可能的结果并将其发送到客户端(通过隐藏输入或 javascript 数据结构),并使用客户端数据作为源自动完成。我敢肯定这会快如闪电,但对我来说似乎很奇怪 - 这样做有什么缺点吗?

是的,有缺点。您是说数据库中有数以万计的可能结果:足以让您怀疑数据库需要几秒钟来从您的查询中返回一些结果。在初始页面加载时将所有这些条目加载到页面中,将对初始页面加载产生巨大的性能影响。它可能会使您的页面大小比需要的大几十万,这对于互联网连接速度较慢的用户来说有很大的不同。

【讨论】:

  • 很好的建议。经过一些分析,我确定大部分时间都发生在数据库上,无论如何我都认为这是。这是有道理的,因为它是一个非常古老的数据库,没有索引、约束或关系——更糟糕的是我不确定我是否可以改变它。我被告知要使用我得到的东西。我可能不得不推动以便在那里放置索引。如果这在政治上不可行,您还能想到其他解决方法吗?
  • @Konrad:啊,我记得在一家大公司工作。节哀顺变。无论如何,如果他们不允许您在数据库字段上添加索引,但他们仍然想要快速响应时间,那么内存缓存可能是要走的路。您可能需要找到或编写一个允许基于StartsWith 标准进行快速查找的集合类:可能是一棵树,其中每个节点都有一个字符,而它的叶子是从根路径中的字符开始的路径。跨度>
  • @Konrad:如果数据库中的值几乎不会改变,另一种选择是使用这些值生成一个静态文件,然后使用缓存设置使文件只加载一次浏览器。看看chinese-tools.com/tools/ime.html如何使用chinese-tools.com/jdd/public/ime/data-utf.js
【解决方案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。它需要一些设置,但它很有效。

Redis autocomplete

efficient serverside autocomplete

【讨论】:

  • 我正在研究 OutputCache,这可能是我需要的
  • 不,不幸的是它缓存了我查询的第一个结果集 - 所以假设我输入“Pr”并得到 Priyank、Proudhon 等 - 然后我输入“Kon”期望得到“Konrad”但我仍然得到我最初键入“Priyank、Proudhon 等”的自动编译术语的结果。
  • 您为什么不尝试第二个选项 [flickr 示例] 并重新考虑您的数据结构和服务器端捕获。我相信没有比使用轻量级数据传输和服务器端捕获更好的解决方案了。
【解决方案3】:

您提到的方式不是一个坏主意 - 但就像 StriplingWarrior 提到的那样,它可能会影响您的页面加载。一种解决方法是在页面加载时执行异步 ajax 调用,并在成功回调中绑定返回到自动完成的数据。

这意味着在返回结果之前,自动完成功能不会起作用,但用户进入文本框并在

【讨论】:

    【解决方案4】:

    我不太确定您的设置,但您可以采用的一种优化路径是使用 redis 将所有可搜索参数存储为键/值对。只需设置一个任务,使其保持更新即可。

    【讨论】:

      猜你喜欢
      • 2010-12-04
      • 2011-08-08
      • 2013-01-22
      • 2016-05-31
      • 2011-10-08
      • 2011-11-16
      • 2017-06-19
      • 2011-08-11
      相关资源
      最近更新 更多