小编典典

如何避免这个非常繁琐的查询使应用程序变慢?

hibernate

我们有一个在生产环境中运行的Web应用程序,有时客户抱怨该应用程序的运行速度很慢。

当我们检查应用程序和数据库的运行状况时,我们发现这个“宝贵的”查询同时由多个用户执行(因此给数据库服务器带来了极高的负载):

SELECT   NULL AS table_cat,
         o.owner AS table_schem,
         o.object_name AS table_name,
         o.object_type AS table_type,
         NULL AS remarks
FROM     all_objects o
WHERE    o.owner LIKE :1 ESCAPE :"SYS_B_0" AND
         o.object_name LIKE :2 ESCAPE :"SYS_B_1" AND
         o.object_type IN(:"SYS_B_2", :"SYS_B_3")
ORDER BY table_type, table_schem, table_name

我们的应用程序不执行此查询,我相信它是一个Hibernate内部查询。我几乎找不到关于为什么Hibernate进行此繁重查询的信息,因此非常感谢您对如何避免它的任何帮助!

生产环境信息:Red Hat Enterprise Linux 5.3(Tikanga),JDK 1.5,Web容器OC4J(whitin Oracle
Application Server),Oracle数据库10.1.0.4,用于JDK
1.2和1.3的JDBC驱动程序,Hibernate版本3.2.6.ga,连接池库C3P0版本0.9.1。

更新
:感谢@BalusC掌握了确实由Hibernate执行查询的功能,现在我对发生的事情有了更好的了解。我将解释我们处理hibernate会话的方式(是非常简单的,如果您对如何更好地处理它有任何建议,欢迎他们!)

我们有一个过滤器(实现javax.servlet.Filter),该过滤器在启动时(init方法)将构造会话工厂(可能仅发生一次)。然后,到达应用程序的每个HttpRequest都会通过过滤器并获得一个
新的 会话,并开始一个事务。流程结束后,它会通过过滤器返回,进行事务提交, 杀死
hibernate会话,然后继续前进页面(我们不会将hibernate会话存储在Http会话中,因为它在我们的测试)。

现在是我认为问题所在的部分。在我们的开发环境中,我们将应用程序部署在Tomcat 5.5中,并且当我们启动该服务时,所有过滤器都会立即启动,并且
启动 一次 。在OC4J的生产环境中,这种方式似乎不起作用。我们部署应用程序,只有在第一个请求到达时,OC4J才会实例化过滤器。

这使我认为OC4J实例化 每个
请求的筛选器(或至少多次,这仍然是错误的),从而在每个请求上创建会话工厂,并执行%&%#%$#查询,从而导致我的问题!

现在,对吗?我有办法配置OC4J使其仅实例化过滤器一次吗?

非常感谢大家抽出宝贵的时间对此做出回应!


阅读 512

收藏
2020-06-20

共1个答案

小编典典

好吧,经过几个月的研究,事实证明问题不是我的Web应用程序。问题是使用数据库的同一实例(不同用户)的其他Oracle Forms应用程序。

发生的事情是Oracle Forms应用程序正在锁定数据库上的记录,因此使数据库的几乎所有工作都非常缓慢(包括我钟爱的Hibernate查询)。

锁定的原因是没有对Oracle Forms应用程序的外键进行索引。因此,正如我的老板向我解释(他找到了原因),当用户在Oracle
Form应用程序中编辑主从关系的主记录时,如果没有其外键索引,则数据库 将锁定整个明细表 。这是因为Oracle
Forms的工作方式是更新主记录的所有字段,包括主键的字段,而外键则引用这些字段。

简而言之, 请不要让外键没有索引 。我们为此受了很多苦。

感谢所有花时间帮助您的人。

2020-06-20