如何提高我的软件项目的速度?

时间:2010-05-18 19:02:45

标签: java database performance hibernate

我正在与Java上的同学一起开展学校软件项目。 我们将信息存储在远程数据库中。

当我们启动应用程序时,我们从数据库中提取所有信息并将其转换为在我们的应用程序中使用的对象(使用java sql statemens)。 在应用程序中,我们编辑其中一些对象,然后在退出应用程序时 我们使用Hibernate保存或更新数据库中的信息。

如您所见,我们不使用Hibernate来提取信息,我们仅将其用于保存和更新。

我们有2个但非常相似的问题。 对象的加载(当我们启动应用程序时)和在db中保存对象(使用Hibernate)(关闭应用程序时)花费了太多时间。 我们的项目不是一个庞大的企业应用程序,它是一个非常小的应用程序,我们只管理一些学生,教师,家庭作业和测试。所以我们的数据库也非常小。 我们怎样才能提高绩效?

稍后编辑:如果我们使用本地数据库它运行得非常快,它在远程数据库上运行速度很慢

11 个答案:

答案 0 :(得分:7)

您是说要将整个数据库加载到内存中然后进行操作吗?如果是这种情况,为什么不简单地将数据库用作存储设备,并根据需要进行查找和操作(如果您愿意,可以使用Hibernate,如果不喜欢,可以使用其他内容)?关键在于确保您使用连接池,因为这会缩短连接时间。

如果这是您正在做的事情,那么您可能也会遇到内存问题 - 首先,通过不将整个数据库缓存到内存中,您将减少内存并将网络负载从开头/结束分散到它需要发生的时候。

答案 1 :(得分:4)

这两句话对我来说是红旗:

  

当我们启动应用程序时,我们拉   来自数据库的所有信息   并将其转换为要使用的对象   在我们的应用程序中(使用java sql   statemens)。在我们编辑的应用程序中   其中一些对象然后我们   退出我们保存或更新的应用程序   使用数据库中的信息   冬眠。

是否有要求原因是您在启动时将数据库中的所有信息加载到内存中,或者为什么要等到关闭以将更改保存回数据库?

如果没有,我建议改变设计。如果您已经为数据库中的表创建了Hibernate映射,那么我将使用Hibernate进行所有CRUD(创建,读取,更新,删除)操作。而且,我只会根据需要加载应用中每个页面所需的数据。

如果此时无法进行那种设计更改,我认为您必须仔细研究如何管理数据库连接。你在使用连接池吗?你打开了多个连接吗?忘了释放它们?

要看的其他东西。你是如何使用Hibernate将实体保存到数据库的?你在做一个getHibernateTemplate()。得到每一个然后在每个上做一个entity.save或entity.update?如果是这样,这意味着您还要使Hibernate在执行保存或更新之前为每个数据库对象运行select查询。因此,基本上,您将加载每个数据库对象两次(一次在程序开头,一次在保存之前)。要查看是否发生了这种情况,您可以打开show_sql property或使用P6Spy查看Hibernate正在运行的查询。

答案 2 :(得分:2)

对于您正在做的事情,最好将序列化对象并将其写入平面文件。

但是,更有可能的是,您应该根据需要直接从数据库中读取/更新对象,而不是一次性完成,因为aperkins提供了所有原因。

另外,请考虑一下如果您的应用程序崩溃会发生什么?如果您的所有更新仅保存在内存中,直到应用程序关闭,如果应用程序意外关闭,一切都将丢失。

答案 3 :(得分:2)

从远程数据库服务器加载所有内容与从本地数据库服务器加载所有内容的区别在于网络延迟/管道大小。网络是一个比其他任何东西都小的管道。两个问题:首先,我们真正谈论了多少数据?第二,你的网络速度是多少? 10/100/1000?由于从网络协议到实际查询本身的所有内容,管道大小的10到20%之间的数字将是开销。

正如其他人所说,你的架构方式通常在“不要做”的列表中很高。启动时,仅提取足够的数据来初始化应用程序。当用户完成它时,拉出你完成该任务所需的内容。

你拉动所有东西的唯一时间是他们在断开状态下工作。在这种情况下,您仍然不会将所有内容作为对象加载到应用程序中,您只需从本地数据存储中工作,该数据存储每隔一段时间就会与远程服务器同步。

答案 4 :(得分:0)

该项目非常完整。我们现在不能对它进行大规模的重构。 保存时我试图为Hibernate使用二级缓存。 EhCacheProvider。

在hibernate.xml中:           net.sf.ehcache.hibernate.EhCacheProvider    

我已经为缓存ehcache.xml做了一个配置:                            

我已将cache.jar放在项目构建路径中 我已经为每个类设置了hibernate属性并在映射中设置。 但是这个缓存似乎没有效果。我不知道它是否有效(如果使用的话)。

答案 5 :(得分:0)

  1. 尝试最小化SQL查询的数量,因为每个查询都有自己的开销。
  2. 您可以启用数据库压缩,这可以在有大量数据时加快速度。
  3. 也许您多次连接数据库?
  4. 检查远程数据库服务器的ping时间 - 可能是问题。

答案 6 :(得分:0)

由于您的应用程序在远程数据库服务器上运行时速度很慢,我认为性能损失是由于:

对于休眠,您可以使用其批处理功能并调整hibernate.batch_size

在所有情况下,尤其是当您无法重构代码库的较大部分时,请使用 profiler (方法时间或SQL查询)来查找瓶颈。我打赌你会发现成千上万的查询,每个查询需要10毫秒RTT),这些查询可以合并为一个。

答案 7 :(得分:0)

您可以查看其他一些事项:

  • 您可以为JVM分配更多内存
  • 使用jconsole工具调查瓶颈是什么。

答案 8 :(得分:0)

为什么你没有两个独立的线程?

线程1将逐个加载对象。 线程2将在加载对象时对其进行处理。

您的应用在启动时看起来会更具互动性。

答案 9 :(得分:0)

审查基础知识从未受到伤害:

提高速度意味着缩短时间(显然),为此,您会发现需要花费大量时间的活动,但可以被消除或替换为使用更少时间的。我所说的 activity 几乎总是函数调用,方法调用或属性调用,在特定目的的特定代码行上执行。如果可以调用I / O或者它可以调用计算,或者两者都调用。如果其目的不是必要的,那么它可以进行优化。

许多人使用分析器来尝试找到这些浪费时间的代码行,但是大多数分析器都会错过目标,因为它们会查看功能,而不是线路,它们在I / O期间进入睡眠状态,并且他们担心“自我时间” ”

更多人试图猜测可能是什么问题,或者他们要求别人猜测,例如通过询问SO。从猜测的性质来看,这种猜测有时是正确的 - 通常不是,但人们仍然在其中投入时间和资源。

有一种非常简单的方法可以确定,无需猜测,可以有效地优化什么,here is one way to do it in Java

答案 10 :(得分:0)

感谢您的回答。他们的帮助很大。 我们完全解决了这个问题:

重构了LOAD代码。现在它使用Hibernate和Lazy Fetching。 重构了SAVE代码。现在它只保存修改后的数据以及修改后的数据。这样,除了结束,我们没有巨大的成功。

我很惊讶这一切都有多好。我们必须编写的新代码量非常小。