Oracle 如何避免这个会减慢应用程序速度的非常繁重的查询?

Oracle 如何避免这个会减慢应用程序速度的非常繁重的查询?,oracle,hibernate,orm,jdbc,oas,Oracle,Hibernate,Orm,Jdbc,Oas,我们有一个在生产环境中运行的web应用程序,在某个时候客户抱怨应用程序速度太慢 当我们检查应用程序和数据库的运行情况时,我们发现这个“宝贵的”查询同时由多个用户执行(从而对数据库服务器造成极高的负载): 我们的应用程序不执行这个查询,我相信它是一个Hibernate内部查询。关于为什么Hibernate会执行这个极其繁重的查询,我几乎找不到什么信息,因此非常感谢您对如何避免它的任何帮助 生产环境信息:Red Hat Enterprise Linux 5.3(Tikanga)、JDK 1.5、we

我们有一个在生产环境中运行的web应用程序,在某个时候客户抱怨应用程序速度太慢

当我们检查应用程序和数据库的运行情况时,我们发现这个“宝贵的”查询同时由多个用户执行(从而对数据库服务器造成极高的负载):

我们的应用程序不执行这个查询,我相信它是一个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对claryfing的支持,确实是Hibernate执行了查询,现在我对正在发生的事情有了更好的了解。我将解释我们处理hibernate会话的方式(这是非常基本的,是的,如果您有关于如何更好地处理它的建议,他们将非常受欢迎!)

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

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

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

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


非常感谢大家花时间回答这个问题

我相信这个查询来自Oracle JDBC驱动程序,它实现了一个Hibernate请求,通过DatabaseMetaData检索数据库对象信息


这个查询不应该太贵,或者至少不在我手边的系统上。您对所有对象的计数是多少?更重要的是,您在解释计划的行/字节总数中看到了什么?

您的10g数据库中的sys模式是否使用更新的统计数据进行分析?您是否收集了sys模式中固定表的统计信息。对系统来说,查询所有的_对象不应该太费力。如果您通过autotrace/tkprof运行查询,那么将花费的主要资源是什么/在哪里。

它确实来自Hibernate,特别是
org.Hibernate.tool.hbm2ddl.TableMetadata
。它位于每个用于验证模式(表和列映射)的目录下。显然,它不必要地在每个派生的请求或会话上执行,而不是在应用程序启动时只执行一次。例如,您是否在每次请求或会话时都不必要地调用Hibernate配置程序

正如所指出的,此查询是在架构验证期间执行的。但是,在创建
会话工厂时(如果激活),验证通常一次性完成。您是否明确地调用了以下方法:
Configuration#validateSchema(方言,数据库元数据)


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

您对视图中的开放会话的实现看起来很好(与中建议的实现非常接近)。根据Servlet规范,部署描述符中的每个
声明中,每个容器的Java虚拟机(JVMTM)只实例化一个实例。因为OC4J的情况不太可能不是这样,所以我很想说,肯定还有别的东西


你能在过滤器里放一些日志吗?如何使
SessionFactory
静态(在一个好的
HibernateUtil
类中)?

这来自默认的C3PO测试查询。在配置中提供一个更简单的查询。比如,从dual中选择“X”。

好吧,经过几个月的研究,发现问题不是我的web应用程序。问题是其他使用相同数据库实例(不同用户)的Oracle Forms应用程序

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

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

总之,请不要离开你的外国朋友
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
java.sql.DatabaseMetaData#getTables(....)