pla*_*eon 5 performance oracle oracle-11g
我目前面临着从 Java 程序启动的运行缓慢的 Hibernate 查询的问题。它在后端调用 Oracle 11g。
此查询在第一次运行时需要 40-90 秒。然而,在随后的执行中,查询会在很短的时间内返回(我什至没有看到数据库被命中,因此假设休眠正在缓存它)。
如果我将查询从企业管理器复制并粘贴到 SQL 客户端并直接运行相同的查询(甚至更改一些参数),查询将在几分之一秒内返回。
如果我查看 EM 中的性能调整选项卡,我会发现所花费的时间主要用于用户 I/O 等待 (97.5%) 和 CPU (2.5%)。这是否意味着我在休眠中使用的提取大小配置的值太小?
如果您可能需要任何其他信息来帮助我深入了解此问题,请告诉我。
======
我们确实在表上有一个索引,我可以看到它被用作查询执行的一部分,不幸的是它不是很可读,但我不确定如何包含它:
Id Operation Name Rows
(Estim) Cost Time
Active(s) Start
Active Execs Rows
(Actual) Read
Reqs Read
Bytes Mem
(Max) Activity
(%) Activity Detail
(# samples)
0 SELECT STATEMENT 1
1 . FILTER 1
2 .. HASH JOIN RIGHT OUTER 2674 7223 1 +4 1 0 1M
3 ... TABLE ACCESS FULL TOTEM_EQ_EXPIRYCODES 475 4 1 +4 1 481
4 ... HASH JOIN RIGHT OUTER 2674 7219 1 +4 1 0 399K
5 .... TABLE ACCESS BY INDEX ROWID TOTEM_EQ_UNDERLYINGS 1 2 1 +4 1 1
6 ..... INDEX UNIQUE SCAN TOTEM_EQ_UND_PK 1 1 1 +4 1 1
7 .... NESTED LOOPS 1
8 ..... NESTED LOOPS 2674 7216 42 +4 1 0
9 ...... TABLE ACCESS BY GLOBAL INDEX ROWID EQUITIES_MONTHLY_INSTRUMENTS 2671 1871 45 +1 1 8438 3517 27MB 24.44 db file sequential read (11)
10 ....... INDEX RANGE SCAN EQ_MON_INS_UNDERLYING_INDX 2671 12 42 +4 1 8438 27 216KB
11 ...... PARTITION RANGE ITERATOR 1 2 8438
12 ....... INDEX RANGE SCAN EQ_MON_RESULT_INSPT_UNQ 1 2 44 +2 8438 0 5403 42MB 75.56 Cpu (1)
db file sequential read (33)
13 ..... TABLE ACCESS BY LOCAL INDEX ROWID EQUITIES_MONTHLY_RESULTS 1 3
Here are the Global stats:
Elapsed
Time(s) Cpu
Time(s) IO
Waits(s) Fetch
Calls Buffer
Gets Read
Reqs Read
Bytes
45 0.73 45 1 22980 9740 76MB
Run Code Online (Sandbox Code Playgroud)
事实证明,问题与选择作为查询计划一部分的索引有关。
该查询接受一个范围作为其参数集的一部分。由于我现在不打算讨论的原因,我们将范围开始日期和结束日期传递为相同的值。
当我们直接进行调用时,我们对这些参数进行硬编码,Oracle 推断它们代表单个日期,而当通过代码传递它们时,范围作为绑定变量传递。
这意味着 Oracle 选择在一种情况下扫描所有分区,而在另一种情况下选择扫描特定分区。
我们最终通过仅传递一个日期参数来修复查询,因为我们意识到我们不需要范围!
诚然,这是一个相当特殊的情况!