【问题标题】:What are my options for optimizing this Spring/Hibernate page?我有哪些优化这个 Spring/Hibernate 页面的选项?
【发布时间】:2010-11-29 22:32:34
【问题描述】:

我有一个涉及数据库中大量数据的页面。它显示了大量数据,并且还对其进行了大量计算,这在按查询分组或在存储过程中执行将是一个非常麻烦的事情。有了域模型,一切就容易多了。

无论如何,Hibernate 最终会在提取所有数据时进行大量查询。我是急切还是懒惰地获取数据并不重要……所有查询总计约 600-700 毫秒。

单个查询非常快。它们甚至不到 1 毫秒。但正如您所见,此页面对列出 58 名学生的培训课程结果的表格进行了大量查询:

0 ms  JDBC SELECT (MODULE)
0 ms  JDBC SELECT (TASK)
0 ms  JDBC SELECT (USER_ACCOUNT) // student #1
0 ms  JDBC SELECT (ACTIVE_TASK)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (USER_ACCOUNT)
0 ms  JDBC SELECT (ACTIVE_TASK)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (USER_ACCOUNT)
0 ms  JDBC SELECT (ACTIVE_TASK)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)

0 ms  JDBC SELECT (USER_ACCOUNT) // student #2
0 ms  JDBC SELECT (ACTIVE_TASK)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (QUESTION)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (KEYWORD)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_FILL_IN_THE_BLANK_ANSWER)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_FILL_IN_THE_BLANK_ANSWER)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)

0 ms  JDBC SELECT (USER_ACCOUNT) // student #3
....
0 ms  JDBC SELECT (USER_ACCOUNT) // student #58
0 ms  JDBC SELECT (ACTIVE_TASK)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (ACTIVE_QUESTION)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_LANGUAGE_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)
0 ms  JDBC SELECT (QUESTION_RESULT_TO_KEYWORD)

30-60 名学生参加一门课程是很常见的,因此 600-700 毫秒会杀死服务器。

为了说明复杂性,这里是 1-M 关系:

模块(1)->任务->问题->关键字

ActiveModule(1)->ActiveTask->ActiveQuestion->QuestionResult->关键字、LanguageKeyword

此外,还有其他 1-M 链接:

模块->ActiveModule

任务->活动任务

问题->主动问题

基本上,这是一个非常复杂的数据图。

我有哪些选择?运行此应用程序的服务器只有 1 GB 的 RAM,因此缓存单个对象几乎是不可能的。我不知道让 Hibernate 发出更少的查询是否会产生很大的不同。就这么多。

这个应用程序的架构非常类似于树,而且深度和复杂。不幸的是,所有这些数据都是必需的。树木基本上全有或全无。

【问题讨论】:

  • 你能在数据库上设置查询缓存吗?这可能会有所帮助。您可能还可以调整其他参数来帮助调整数据库以支持此级别的流量。
  • 哦,男孩...我希望我有用于查询缓存的 ram。我可以 这样做——例如,我有权这样做。但是这个服务器没有它的内存。它已经用尽了 :( 如果我有更多的 RAM 可以使用,那将是我要做的第一件事。不过建议很好。

标签: java database performance hibernate spring


【解决方案1】:

使用视图。这应该会优化您的联接并减少您必须执行的单个查询的数量。

【讨论】:

  • 连接并不是真正的问题。真正的观点是,将它从数据库中取出并在其上运行计算将会非常混乱。这真的是唯一的选择吗?此外,可能很难查看所有这些数据。最终结果是非常密集的计算,并且一个视图实际上不会起作用,因为计算都发生在不同的级别上。当我从逻辑上看待问题时,在 java 域模型中执行它很容易成为解决问题的最佳方法:/
【解决方案2】:

我认为您可以使用一两个加入

的 sql 查询轻松地做到这一点

ActiveModule(1)->ActiveTask->ActiveQuestion->QuestionResult->关键字、LanguageKeyword

您甚至可以在数据库引擎上卸载一些计算。

这种事情对于任何现代数据库来说都是微不足道的,忽略休眠并只通过原始 SQL 查询。

【讨论】:

  • 如果我只使用几个查询,那将是有史以来最大的交叉产品。事实是,我需要每个实体上的所有列,并且我需要它们的关系。我可以卸载数据库中的一些工作......但是我将我的业务逻辑分成两个不同的地方......而且我也失去了它的自动化单元测试和使用好的编程语言(用 SQL 编写复杂的东西是垃圾)。事实上,当我针对 hsqldb 运行时,我必须开始禁用一堆测试,这是将这些东西放入数据库的另一个缺点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-21
  • 2014-10-28
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多