2016-02-22 68 views
0

我有Java应用程序,它使用Spring JPA和Hibernate连接到ORACLE 11g数据库。休眠等效skip_unusable_indexes(oracle)

有时,我需要drop partition在DB和重建所有UNUSABLE global indexes为USABLE状态。 (索引由于drop分区命令而变得不可用)

在我的分区被删除的时间和UNUSABLE索引尚未重建之间,我的联机应用程序失败,如下所示ORA-01502 error

Caused by: java.sql.BatchUpdateException: ORA-01502: index 'USER.INDEX_NAME' or partition of such index is in unusable state 

    at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10070) 
    at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:213) 
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) 
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) 
    ... 94 more 

在SQL存在通过设定skip_unusable_indexes=TRUE忽略不可用索引的选项。通过这种方式,查询优化器选择了一个不使用索引的不同(昂贵)执行计划,并且由于不可用的索引而不报告DML查询的任何故障。

在Hibernate中有没有这样的类似选项,当索引处于UNUSABLE状态时,我可以使用它来不失败?

版本我使用 休眠:3.6.9 甲骨文:11g的 的Java:7

回答

0

您可以尝试执行:

ALTER SESSION SET skip_unusable_indexes=true 

this,但本次会议将返回集合池并重用,这将影响多个查询。

如果我是你,我会问自己“为什么我的索引无法使用?”这种情况不应该发生,除非您正在执行一些维护或执行一些非常大的批处理过程。你可能有一个24/7系统,你不会停止系统的维护。在这种情况下,您可以将系统选项设置为明智,而不需要对代码进行任何更改。这样系统会变慢,但在维护期间表现得更好。 请记住,用于强制执行约束的索引不能被忽略,插入/更新查询将无法继续执行。并添加一些自动检查,在某些时候报告PRO中的不可用索引。就在PL/SQL过程,发送电子邮件就可以OK

另一种方法是只在数据库中的变化而改变的选项:

ALTER SYSTEM SET skip_unusable_indexes=true; 
ALTER TABLE T1 DROP PARTITION P1; 
ALTER INDEX I1 REBUILD ONLINE 
ALTER SYSTEM SET skip_unusable_indexes=false; 

dba.stackexchange.com有一个关于更好的方式来删除一个讨论划分。所以你并不孤单,但解决方案是针对Oracle 12C。

+0

正如你所说的,索引不应该处于不可用状态,但不可用索引是在索引正在构建时在锁定表之间脱节并且允许在表中使用DML而不使用Oracle 11g中的索引。如果我使用'ALTER TABLE T1 DROP PARTITION P1 REBUILD GLOBAL INDEXES'这样的语句,那么我的表将被锁定,直到重建索引。但是,如果我使用2个单独的语句,如'ALTER TABLE T1 DROP PARTITION P1; ALTER INDEX I1 REBUILD ONLINE“,那么当重建索引时,我的DML不会被阻塞。但不幸的是,由于索引错误不可用,hibernate插入似乎失败。 – Sauchin

+0

为什么不能: ALTER SYSTEM SET skip_unusable_indexes = true; ALTER TABLE T1 DROP PARTITION P1; ALTER INDEX I1 REBUILD ONLINE; ALTER SYSTEM SET skip_unusable_indexes = false; – borjab

+0

如果可以在系统级别修改skip_unusable_indexes,是否可以再次检查?看起来像[Oracle文档](http://docs.oracle。com/cd/B10501_01/server.920/a96540/statements_22a.htm)'SKIP_UNUSABLE_INDEXES只是一个会话参数' – Sauchin