如何避免这种非常繁重的查询会降低应用程序的速度?

Jua*_*des 5 oracle orm hibernate jdbc oas

我们有一个在生产环境中运行的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
Run Code Online (Sandbox Code Playgroud)

我们的应用程序不执行此查询,我相信它是一个Hibernate内部查询.我发现很少有关于为什么Hibernate会执行这个极其繁重的查询的信息,所以任何有关如何避免它的帮助都非常感谢!

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

更新:感谢@BalusC for claryfing确实是Hibernate执行查询,现在我对正在发生的事情有了更好的了解.我将解释我们处理hibernate会话的方式(这是非常基本的,如果你有关于如何更好地处理它的建议,我们非常欢迎!)

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

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

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

现在,这是正确的吗?有没有办法让我配置OC4J才能实例化一次过滤器?

非常感谢大家花时间回复此事!

Jua*_*des 2

好吧,经过几个月的观察,发现问题不在于我的 Web 应用程序。问题出在使用同一数据库实例(不同用户)的其他 Oracle Forms 应用程序。

发生的情况是,Oracle Forms 应用程序锁定了数据库上的记录,因此几乎所有数据库工作都变得极其缓慢(包括我喜爱的 Hibernate 查询)。

锁定的原因是 Oracle Forms 应用程序的外键均未建立索引。因此,正如我的老板向我解释的那样(他发现了原因),当用户在 Oracle Form 应用程序中编辑主从关系的主记录时,如果外键没有索引,数据库将锁定整个明细表。这是因为 Oracle Forms 的工作方式是更新主记录的所有字段,包括主键字段,即外键引用的字段。

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

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