JDBC 的性能问题

问题描述 投票:0回答:4

我目前面临一个问题,即从我的 Java 应用程序中发出特定 SQL 查询大约需要 30 秒,但是 <1 sec in a SQL-client (SQL Developer).

在问题中,
通过 JDBC 在 Java 中查询速度慢,但在其他系统 (TOAD) 中则不然,建议使用绑定到 java 变量的PreparedStatement 可能会使查询执行速度比在 SQL 客户端(在这种情况下是 TOAD)中慢得多,因为 Oracle对使用哪些索引感到困惑。这是否也是不带参数的PreparedStatement的问题?

否则问题可能是什么?

查询看起来像这样

select 
sum(col1),
sum(col2),
max(select ...)
from view_
where time_id = get_time_id(to_date('2010-10-10','yyyy-mm-dd'))

其中 view_ 是一个复杂视图,包含表和其他复杂视图的聚合。该查询作为PreparedStatement 执行,但不带任何参数。无论我们使用准备好的语句还是仅使用简单的语句,似乎都没有什么区别。

由于执行计划相当庞大,我无法在这里发布所有内容,但相关差异似乎是:

UNION-ALL
表访问完全 GVC_WH.PLAYER_FACT_DAILY 表 37 6717151 596,934.317 19940 240 7621178231 19502
UNION-ALL
按索引 ROWID 访问表 GVC_WH.PLAYER_FACT_DAILY 表 38 2657 236.120 2429 30 20544658 2428
索引范围扫描 GVC_WH.PK_AGG_PLAYER 索引(唯一) 37 2657 16 1 638743 16

第一个片段来自使用 JDBC 瘦客户端运行时的片段,第二个片段来自在 SQL Developer 中运行时的片段。当使用 JDBC Thin Client 作为语句运行时(无论我是否使用准备好的语句都没有区别),它没有选择正确的索引。第一次的时间差为 30 秒,第二次的时间差为 0.5 秒。

是否使用函数 get_time_id 会禁止在通过 JDBC 使用索引时使用索引,即使它在列上不起作用,即使它似乎在 SQL Developer 中工作?

oracle jdbc
4个回答
2
投票

我会尝试在使用应用程序时在数据库上运行trace

然后您应该能够看到正在运行的查询以及实际的执行计划。这将准确地向您显示发生了什么,即是否正在获取索引。


1
投票

由于传入谓词,您很可能会遇到绑定变量峰值问题。尝试使用以下命令运行查询来确认(即一致的运行时间)

alter session set “_optim_peek_user_binds”=false;

所有对象的统计数据都是最新的吗?

正如贾斯汀所言,确保您的测量也正确。如果没有完整的查询,将很难提供额外的见解。


0
投票

检查以确保有人没有设置属性 oracle.jdbc.defaultNChar=true

有时这样做是为了解决 unicode 问题,但这意味着所有列都被视为 nvarchar。如果你在 varchar 列上有索引,则不会使用它,因为 oracle 必须使用函数来转换字符编码。


0
投票

如果原点是 FORCE,只需将 Cursor_Sharing 更改为 EXACT

© www.soinside.com 2019 - 2024. All rights reserved.