Java ORA-01013仅在第一次选择执行时

Java ORA-01013仅在第一次选择执行时,java,sql,oracle,spring-data,query-optimization,Java,Sql,Oracle,Spring Data,Query Optimization,我有一个java程序,它使用Spring框架中的JdbcTemplate类对Oracle数据库执行各种SELECT查询 每次我在长时间暂停(1-2天)后运行此程序时,它都会被阻止执行特定的查询,在等待10分钟后,我会收到一个超时异常,并出现ORA-01013错误。如果我再次运行该程序,它将执行良好,没有任何错误 具体查询为: SELECT ca.ARTICLE as article, r.COUNTRY as country, count(1) as total FROM CLIENT_

我有一个java程序,它使用Spring框架中的JdbcTemplate类对Oracle数据库执行各种SELECT查询

每次我在长时间暂停(1-2天)后运行此程序时,它都会被阻止执行特定的查询,在等待10分钟后,我会收到一个超时异常,并出现ORA-01013错误。如果我再次运行该程序,它将执行良好,没有任何错误

具体查询为:

SELECT ca.ARTICLE as article, r.COUNTRY as country, count(1) as total
    FROM CLIENT_ARTICLES ca 
      INNER JOIN ARTICLES aa ON a.ID = substr(ca.ARTICLE, 0, 8) 
      INNER JOIN SEAZON_P sp ON sp.PARAM = 'paramS1' AND substr(a.id, 1, 1) = sp.seazon 
      INNER JOIN REGISTER r ON r.id = ca.CLIENT_ID 
    WHERE ca.ACTION_DATE > sysdate - 5 AND ca.ACTION = 'I' 
    GROUP BY ca.ARTICLE, r.COUNTRY 
    ORDER BY ca.ARTICLE, r.COUNTRY;
此查询的解释计划:

Plan hash value: 3771965889

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                       | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                            |    11 |   759 | 71934   (2)| 00:14:24 |       |       |
|   1 |  SORT ORDER BY                   |                            |    11 |   759 | 71934   (2)| 00:14:24 |       |       |
|   2 |   HASH GROUP BY                  |                            |    11 |   759 | 71934   (2)| 00:14:24 |       |       |
|   3 |    NESTED LOOPS                  |                            |    11 |   759 | 71932   (2)| 00:14:24 |       |       |
|   4 |     NESTED LOOPS                 |                            |    40 |  1920 | 71932   (2)| 00:14:24 |       |       |
|   5 |      NESTED LOOPS                |                            |     2 |    78 | 71928   (2)| 00:14:24 |       |       |
|   6 |       PARTITION RANGE ITERATOR   |                            |     2 |    58 | 71924   (2)| 00:14:24 |   KEY |1048575|
|*  7 |        TABLE ACCESS FULL         | CLIENT_ARTICLES            |     2 |    58 | 71924   (2)| 00:14:24 |   KEY |1048575|
|   8 |       TABLE ACCESS BY INDEX ROWID| REGISTER                   |     1 |    10 |     2   (0)| 00:00:01 |       |       |
|*  9 |        INDEX UNIQUE SCAN         | PK_REGISTER                |     1 |       |     1   (0)| 00:00:01 |       |       |
|* 10 |      INDEX RANGE SCAN            | PK_ARTICLES                |    20 |   180 |     2   (0)| 00:00:01 |       |       |
|* 11 |     INDEX UNIQUE SCAN            | SEAZON_P_PK                |     1 |    21 |     0   (0)| 00:00:01 |       |       |
-------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

"   7 - filter(""CA"".""ACTION_DATE"">SYSDATE@!-3 AND ""CA"".""ACTION""='I')"
"   9 - access(""R"".""ID""=""CA"".""CLIENT_ID"")"
"  10 - access(""A"".""ID""=SUBSTR(""CA"".""ARTICLE"",0,8))"
"  11 - access(""SP"".""SEAZON""=SUBSTR(""CA"".""ID"",1,1) AND ""A"".""PARAM""='paramS1')"
执行查询的java代码:

public List<ArticleDTO> select(final String param) {
        List<ArticleDTO> articleList;
        String[] queryArgs = { param};
        super.jdbcTemplate.setFetchSize(20000);

        articleList = super.jdbcTemplate.query(SELECT_ARTICLES, queryArgs, this.articleRowMapper);

        return articleList;
    }
公共列表选择(最终字符串参数){
物品清单;
字符串[]queryArgs={param};
super.jdbcTemplate.setFetchSize(20000);
articleList=super.jdbcTemplate.query(选择_ARTICLES、queryArgs、this.articleRowMapper);
退货清单;
}
查询返回80000多个结果,但表非常大(>1000万行)

你知道这可能是个问题吗

谢谢大家!

“我在等待10分钟后,收到一个超时异常 ORA-01013错误。如果我再次运行该程序,则不会出现错误 “任何错误”

ORA-01013的含义是用户请求取消当前操作。所以最可能的解释是您的Spring层被配置为在十分钟后超时请求。但第二次成功,因为相关数据存储在数据库内存和/或操作系统缓存中

那么,你能做些什么来改善情况呢?钝器用于检查超时参数并增加它。这将是最快的胜利,但可能会引起争议。减少执行时间是可取的,但需要更长的时间,因为您需要进行一些调查和测试

你的问题值得注意的一点是:

查询返回超过80000个结果,但表非常大(>1000万行)

您的解释计划中的
数字远没有达到这个量级。乐观主义者认为你的CLIENT_文章中的filter会在每个分区返回两行,对于如此大的表来说,这似乎有点低。所以首先要检查的是表格统计数据的新鲜度。准确的统计数据有助于优化器找到一个好的执行计划


另一件事是查询正在范围内的分区上运行一个完整的表扫描(以
ca.ACTION\u DATE>sysdate-5
so五个或六个分区为边界)。如果表很宽(很多列),那么这是一个昂贵的操作,而您只需要投影中的项目和过滤器中的操作。如果这是一个经常运行的查询,您可能会从(文章、操作)上的本地分区索引中获益。

让一个DB人员知道如何分析执行计划并创建缺少的索引。这也可能有助于调整DB设计。像这样使用substr
a.ID=substr(ca.ARTICLE,0,8)
可以防止正常索引的使用。您可能不需要函数索引,但如果可能的话,我强烈建议您调整数据库设计。您能验证一下表是在哪个字段上分区的吗?如果它是在一个字段上分区的(例如“action\u month”),那么当您限制基于该字段的选择时,查询将只从几个分区中检索数据,而不是从一个完整的表扫描中检索数据。表客户端文章有以下分区:按范围分区(“action\u DATE”)间隔(NUMTODSINTERVAL(1,'DAY'))(分区)“客户端文章”值小于(截止日期('2014-01-01 00:00:00','SYYYY-MM-DD HH24:MI:SS','NLS\U CALENDAR=GREGORIAN')段创建延迟我知道数据库设计混乱,但知道真正的问题是java进程在第一次执行时被阻塞。是否有办法检查此数据是否在数据库缓存中并将其清除?