通过jdbc执行sql比在plsql中慢好多

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过jdbc执行sql比在plsql中慢好多相关的知识,希望对你有一定的参考价值。

以下是我的SQL语句,表上的数据量有40多万。
SELECT SUM (T032_FORM_SU) FROM T029_FORWARD_SIJI T029 INNER JOIN T032_FORWARD_SIJIM ON
T029_WAREH_CD = T032_WAREH_CD
AND T029_OWNER_CD = T032_OWNER_CD
AND T029_SHIPMENT_ID = T032_SHIPMENT_ID
AND T032_TRAN_KBN < '3'
WHERE
T029_WAREH_CD = ?
AND T029_OWNER_CD = ?
AND T029_SLIP_KBN <> '4'
AND T029_SLIP_KBN <> '5'
AND T029_SLIP_KBN <> '9'
AND T029_SHIPMENT_KBN = '01' AND T029.T029_TRAN_KBN < '3'
通过jdbc动态绑定参数执行要10多秒才能完成,但是如果在plsql中执行,条件直接付值,也就是0.1秒左右就好了。不知道这是什么问题,而且通过jdbc执行时,如果不动态绑定参数,直接付值的话也非常快,就是一动态绑定参数,就慢了,这是什么原因。
t029是主表,t032是明细表。 这两个表都建有索引。
结果只一条数据

大哥,plsql是只检索出前面的20条,即rownum<20 的数据,JDBC是查全部。你把PLSQL的数据全展开,你看看要多少秒! 参考技术A --重点在于使用了绑定变量,详解如下:

使用绑定变量,这是导致性能问题的一个主要原因,也是阻碍可扩缩性的一个重要因素。

开发人员在大多数情况下都会使用绑定变量。如果你确实想让Oracle 缓慢地运行,甚至几近停顿,只要根本不使用绑定变量就可以办到。
绑定变量(bind variable)是查询中的一个占位符。例如,要获取员工123 的相应记录,可以使用以下查询:
select * from emp where empno=123;
或者,也可以将绑定变量:empno 设置为123,并执行以下查询:
select * from emp where empno=:empno;
在典型的系统中,你可能只查询一次员工123,然后不再查询这个员工。之后,你可能会查询员工456,然后是员工789,如此等等。如果在查询中使用直接量(常量),那么每个查询都将是一个全新的查询,在数据库看来以前从未见过,必须对查询进行解析、限定(命名解析)、安全性检查、优化等。简单地讲,就是你执行的每条不同的语句都要在执行时进行编译。
第二个查询使用了一个绑定变量:empno,变量值在查询执行时提供。这个查询只编译一次,随后会把查询计划存储在一个共享池(库缓存)中,以便以后获取和重用这个查询计划。
以上两个查询在性能和可扩缩性方面有很大差别,甚至可以说有天壤之别。
从前面的描述应该能清楚地看到,与重用已解析的查询计划(称为软解析,soft parse)相比,解析包含有硬编码变量的语句(称为硬解析,hard parse)需要的时间更长,而且要消耗更多的资源。硬解析会减少系统能支持的用户数,但程度如何不太明显。这部分取决于多耗费了多少资源,但更重要的因素是
库缓存所用的闩定(latching)机制。硬解析一个查询时,数据库会更长时间地占用一种低级串行化设备,这称为闩(latch)。这些闩能保护Oracle 共享内存中的数据结构不会同时被两个进程修改,而且如果有人正在修改数据结构,则不允许另外的人再来读取。对这些数据结构加闩的时间越长、越频繁,排队等待闩的进程就越多,等待队列也越长。你可能开始独占珍贵的资源。有时你的计算机显然利用不足,但是数据库中的所有应用都运行得非常慢。造成这种现象的原因可能是有人占据着某种串行化设备,而其他等待串行化设备的人开始排队,因此你无法全速运行。数据库中只要有一个应用表现不佳,就会严重地影响所有其他应用的性能。如果只有一个小应用没有使用绑定变量,那么即使其他应用原本设计得很好,能适当地将已解析的SQL 放在共享池中以备重用,但因为这个小应用的存在,过一段时间就会从共享池中删除已存储的SQL。这就使得这些设计得当的应用也必须再次硬解析SQL。真是一粒老鼠屎就能毁了一锅汤。本回答被提问者采纳
参考技术B 正确

为什么这个通过PHP / FastCGI在IIS中运行的java程序比在shell中慢得多?

今天我遇到了一个相当奇怪的表现java程序。

在cmd shell中测试java程序会导致执行速度非常快(~0.5s)。使用PHP脚本通过IIS访问相同的Java会导致每个请求的等待时间为5.5秒。

我将-Xprof添加到java调用中以查看它的行为,并找到了这样的重复模式:

Flat profile of 0.25 secs (24 total ticks): SeedGenerator Thread

  Thread-local ticks:
100.0%    24             Blocked (of total)

最后,我们得到以下时间结果:

  Thread-local ticks:
 91.4%   448             Blocked (of total)
  2.4%     1             Unknown: no last frame
lat profile of 5.04 secs (452 total ticks): SeedGenerator Thread

  Interpreted + native   Method                        
  0.2%     0  +     1    java.lang.Object.notifyAll
  0.2%     0  +     1    Total interpreted

     Compiled + native   Method                        
 99.6%    27  +   423    sun.security.provider.SeedGenerator$ThreadedSeedGenerator.run
 99.6%    27  +   423    Total compiled

         Stub + native   Method                        
  0.2%     0  +     1    java.lang.System.currentTimeMillis
  0.2%     0  +     1    Total stub


Global summary of 5.55 seconds:
100.0%   492             Received ticks
  1.8%     9             Compilation
  0.2%     1             Other VM operations
  0.6%     3             Unknown code

代码在SeedGenerator中花费5秒,在此期间java.exe占用一个完整的cpu线程。我试过运行FastCGI开启或关闭模拟,它不会改变结果。

答案

似乎有一些特定于FastCGI模块如何产生新线程的东西。我的第一个猜测是,为模拟创建用户环境需要很长时间,但正如问题所示,这不是真的。然而,在寻找SeedGenerator的问题时,我遇到了这个答案:Simple Java program 100 times slower after plugging in USB hotspot

使用建议的修复程序更改java.security会将执行时间降低到预期值:

Global summary of 0.53 seconds:
100.0%    43             Received ticks
 14.0%     6             Compilation
  4.7%     2             Class loader
  7.0%     3             Unknown code

从观察到的行为来看,假设使用带有FastCGI的IIS上的PHP通过shell_exec创建一个新进程并不能提供任何提供者sun.security.provider.Sun可以用来生成足够的熵以使用加密函数并因此停止执行直到创建足够的熵。

以上是关于通过jdbc执行sql比在plsql中慢好多的主要内容,如果未能解决你的问题,请参考以下文章

在 AIX/bash 上的 bash 循环中读取文件比在 Linux/ksh 中慢得多 - BLOCKSIZE?

Oracle ODP.NET 托管驱动程序在 64 位中的运行速度比在 32 位中慢 50-100%

怎么使用plsql查看执行计划

理解性能的奥秘——应用程序中慢,SSMS中快——SQL Server如何编译动态SQL

怎么使用plsql查看执行计划

为啥 PLSQL 比 SQL*Plus 慢