【问题标题】:speed up data access in a search form加快搜索表单中的数据访问
【发布时间】:2014-07-02 23:50:09
【问题描述】:

在使用 hibernate 和 JPA 的 spring mvc 应用程序中,我有一个 keyword 类,它使用户能够在底层数据库中搜索记录。 JSP 在蒲公英数据表中有一个搜索框,用户键入文本以减少 keyword 选项的数量,直到搜索结果包含足够短的 keywords 列表,用户可以从中选择要搜索的单词用于他们的搜索。

问题是底层数据表中有 80,000 个keywords,我的应用程序需要 20 分钟才能将所有这些 keywords 发送到 JSP,即使我在底层上放置了索引用于搜索的字段的数据库表。有没有什么方法可以设置成keywords 仅在搜索框中输入至少 3 个字符的文本时才发送到 JSP?

这是我的controller 方法:

@RequestMapping(value = "/search", method = RequestMethod.GET)
public String processFindForm(
        ConcWordKey wordkey, HttpServletRequest request, BindingResult result, Map<String, Object> model) {

    Collection<ConcWordKey> results = this.clinicService.findKeyWord("");
    System.out.println("results.size() is: "+results.size());
    model.put("selections", results);
    return "search";
}  

这里是 JSP 的相关部分:

<datatables:table id="keywords" data="${selections}" cdn="true" row="kw" theme="bootstrap2" 
      cssClass="table table-striped" paginate="true" info="false" 
      cssStyle="width: 150px;" align="left" dom="frtp">
    <datatables:column title="Name" cssStyle="width: 150px;" display="html">
        <spring:url value="/search?name={name}" var="searchUrl">
            <spring:param name="name" value="${kw.name}"/>
        </spring:url>
        <a href="${fn:escapeXml(searchUrl)}"><c:out value="${kw.name}"/></a>
    </datatables:column>
</datatables:table>  

这是填充选择的 JPA 方法:

@SuppressWarnings("unchecked")
public Collection<ConcWordKey> findKeyWord(String str) {
    Query query = this.em.createQuery("SELECT DISTINCT wk FROM ConcWordKey wk WHERE wk.name LIKE :wd");
    query.setParameter("wd", str + "%");
    Collection<ConcWordKey> results = query.getResultList();
    return results;
}

【问题讨论】:

  • 引入分页并限制每页数据。
  • @LeosLiterak 谢谢。但是你能告诉我它在代码中的样子吗?
  • @CodeMed 我可以暂时建议一种解决方法,直到我通过蒲公英数据表 API。如果大小小于 3,则在您的控制器中不要总是调用您的 DAO 方法。当输入的关键字长度至少为 3 时,调用数据库以获取结果。同时我为此搜索 altimate 解决方案
  • @Gautam 非常感谢。但我什至不知道如何写超过 3 个字符的检查。
  • 就像你的代码 Collection results = this.clinicService.findKeyWord(inputString);在 inputString 大小小于 3 之前不要执行此行

标签: java spring jsp spring-mvc jpa


【解决方案1】:

我担心客户端性能不佳来自您用于加载数据的方法。我认为 80000 条记录对于 DOM 源来说太多了,尤其是在按键上触发搜索时。

v0.10.0 之前: 我建议您切换到AJAX source(启用分页)。设置需要做更多的工作,但它应该会对性能产生重大影响。 请注意,JSP sample 应用程序确实使用与您相同的技术(Spring、JPA)。随意看看。

但是,如果您真的想继续使用 DOM 源加载数据,您可以简单地取消绑定 keypress 事件处理程序,如 this post 中所建议的那样。要实现它,您需要 Dandelion-Datatables 的 extra JavaScript feature

从 v0.10.0 开始:过滤功能得到了多方面的改进:

当然,仍然建议使用 AJAX 源,但上述功能将进一步改善用户体验。一旦此版本发布,我将使用指向新文档和示例应用程序的正确链接更新此答案。

希望这会有所帮助!

(StackOverflow 要求的免责声明:我是蒲公英的作者)

编辑:蒲公英 0.10.0 发布。已添加链接

【讨论】:

  • +1 感谢您抽出宝贵时间回答这个问题。我详细查看了您的链接。对于我的直接解决方案,我正在做一个解决方法,但我计划在开发长期解决方案时仔细研究您的链接。
【解决方案2】:

EhCache 可能不是您首先需要的。它提供了处理应用程序缓存的能力,这意味着将最常用的对象保存在内存中,以便在需要时更快地访问它们(从内存而不是查询它们)。因此,如果您有 80 000 个关键字,听起来您有 80 000 多个搜索可能性,这意味着:

  • 将它们全部保存在缓存中需要大量内存
  • 您必须全部搜索一次才能将它们放入缓存中

不过,您可能需要一个底层索引系统,例如 Lucene(或 Solar,如果您有多个实例),它将帮助您加快查询速度。这样,您的搜索就会更快,无论之前是否被解雇。

当然,您可以将索引系统与缓存系统结合使用,以获得更好的性能。我的观点是,一开始索引比缓存更重要。

其他一些想法:

  • 请务必启用您的数据库缓存(lvl1 缓存),以便您的查询更快
  • 在您的关键字列上添加数据库索引(也加快了选择查询的速度)

祝你好运!

编辑:查看问题,自动完成功能会更好。例如:http://johnderinger.wordpress.com/2013/01/10/html-autocomplete-with-jpa-rest-and-jquery/

【讨论】:

  • 感谢您抽出宝贵时间回复。我在数据库中添加了一个索引,它至少现在给出了一些初始结果,以向用户显示它在 JSP 冻结时正在做某事。但是还是太慢了。你能用代码告诉我一个具体的解决方案吗?
  • 好吧,我重新阅读了您的问题,建议您使用另一种方法。据我了解,您需要过滤关键字,以便用户可以从轻列表中进行选择。给出您拥有的关键字数量,例如使用自动完成功能可能会更好,这意味着仅加载与用户输入的内容匹配的关键字。因此,您将加载没有标签的页面(然后非常快),并在用户输入时异步加载它们。为了获得更好的性能,仅在他输入至少 3 或 4 个字符时才查询您的数据库。你怎么看?
  • 是的,听起来好多了。谢谢你。但我不知道如何将其放入代码中。你愿意示范吗?
  • 我编辑了我的帖子。你在互联网上有很多自动完成的例子。这是在这里提出广泛问题的一种方式。不过,在实施过程中,如果您在特定部分遇到特定问题,请随时提出另一个问题,我很乐意为您提供帮助
  • 谢谢你,但我认为你让它变得比它需要的更复杂。在 MySQL 命令行客户端中使用 LIKE 的搜索只需要 0.03 秒即可运行。问题是我上面的代码在 JSP 首次加载时加载了整个关键字列表。如果你能告诉我如何让上面代码中的 spring 数据绑定只在用户输入至少 3 个字符后发生,那么这个问题就会得到回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-23
相关资源
最近更新 更多