dav*_*lab 27 java oracle performance jdbc oracle11g
正如此处详述并在此处确认的那样,Oracle在通过JDBC查询数据时返回的默认行数是10.我正在开发一个必须读取和比较数据库中大量数据的应用程序.我认为,如果我们只增加到defaultRowPrefetch1000,那么我们的应用程序肯定会更快.事实证明,它的表现较慢,约为20%.
然后,我们决定从10开始慢慢增加数字,看看它的表现如何.我们已经看到将其设置在100到200之间,大约增加了10%.但是,我绝不会猜到,将它设置得更高会使我们的应用程序执行速度变慢.任何想法为什么会这样?
谢谢!
编辑:
为了澄清,我使用的是Oracle 11g R2和Java 6.
编辑2:
好吧,我想重申我的问题要清楚,因为从下面的答案来看,我并没有正确地表达自己:
如果我设置更高的提取大小,我的应用程序执行速度有多快?对我来说,这听起来像是在说"我们正在为您提供更快的互联网连接,即更胖的管道,但您的网页浏览速度会更慢.
所有其他事情都是平等的,正如我们在测试中所做的那样,我们对我们的应用程序如何只通过这一次更改表现更差感到非常好奇.
Apr*_*ion 23
可能的解释:
Java无所作为,而Oracle正在计算前1000行而不是前10 行.
Oracle无所事事,而Java正在计算最后1000行而不是最后10 行.
通信协议(例如TCP/IP)等待很多,然后必须一次处理更多数据,但峰值数据传输将受到硬件限制的限制.这可以通过协议的开销来抵消,因此应该有最佳的提取大小,任何更少或更多的都会更慢;))
如果获取过程与其他Java代码同步,则会变得更糟,因此Java只在处理完之前的数据后才会请求更多行,而Oracle同时不做任何事情.
想象一下有3个人:
- 第一个将A4纸折成两半
- 第二个将一叠折叠纸从一个房间带到另一个房间
- 第3个从折叠的纸上切下一些形状.
堆栈有多大,如果第一个必须等到第二个返回而第二个必须等到第三个完成他们的工作?
1000的堆栈将不会比10的堆栈更好我猜;))
Ada*_*kes 12
和所有事情一样,没有任何FAST=TRUE设定.虽然JDBC默认提取大小为10并不适合您的情况,但对于"典型"OLTP应用程序来说,它是可以的,对您的情况来说,这似乎也不是那么糟糕.显然,大的提取大小也不适合您的情况.但同样,一次完成1000 并不是那么糟糕.
你没有提到的另一个因素是如何WIDE该行正在拉.考虑到您从数据库服务器通过网络提取到应用服务器的数据块是sum(WIDTH*ROWS).如果你的行是5000字节,并且你一次拉1000,那么每次获取将带来5 MB的数据.在另一种情况下,也许你的行只有100个字节的"瘦".然后取出其中1000个只穿梭100K左右.
因为只有你可以知道回来的数据是什么样的,所以建议在系统范围内为"常规"情况设置提取大小,然后根据需要单独调整奇怪的查询.
一般来说,我也发现100是大数据流程的更好设置.这不是推荐,而是转发观察.
正确的方法是使用setFetchSize.
默认情况下,当Oracle JDBC运行查询时,它会从数据库游标中一次检索10行的结果集.这是默认的Oracle行提取大小值.您可以通过更改行获取大小值来更改每次访问数据库游标时检索的行数.
标准JDBC还允许您为查询指定每个数据库往返提取的行数,此数字称为提取大小.在Oracle JDBC中,行预取值用作语句对象中的默认提取大小.设置提取大小会覆盖row-prefetch设置,并影响通过该语句对象运行的后续查询.
获取大小也用于结果集.当语句对象运行查询时,语句对象的提取大小将传递给查询生成的结果集对象.但是,您还可以在结果集对象中设置提取大小,以覆盖传递给它的语句提取大小.
顺便说一句,至少对于Oracle,您需要小心提取大小,因为Oracle驱动程序会为每行占用的最大可能大小而不是实际数据大小留出一个数组.因此,如果你有一个胖桌子,你的内存占用可能会受到影响.
看看这里 - http://www.oracle.com/technetwork/database/enterprise-edition/memory.pdf
在Oracle中,您可以找到user_tab_columns元数据表(data_length)中列所占用的最大空间.它可用于确定提取大小.
在粗略测试中,我发现4*1024*1024/sum(表的所有列的data_length)是合理的提取大小.
| 归档时间: |
|
| 查看次数: |
29149 次 |
| 最近记录: |