Java应用程序的Oracle TNS效率低下(许多往返,延迟)的任何解决方案吗?
-
28-09-2019 - |
题
我正在寻找一个非常慢的SQL查询(使用JBOSS 5.1中部署的Hibernate起源于Java应用程序)。该特定查询返回了约10k记录,但仍花费了40秒或更多。
我最终用数据库嗅探流量(Wireshark有一个用于TNS的解剖器),并发现了一些意外的东西。当数据来自服务器时,每个结果行都是自己的TNS数据包。此外,在从数据库发送下一个TNS(即应用程序服务器)之前,客户端(即应用程序服务器)确认了每个TNS数据包。对于10K记录,有10k往返数据包并确认它。对性能的影响很大。
这非常低效。 TCP允许更大的数据包,并具有许多机制(滑动窗口,延迟的ACK),以减少延迟并增加吞吐量。但是,在这种情况下,最重要的是TNS协议增加了自己的谈判。
如果我从Oracle的SQL开发人员中运行相同的查询,则不会看到此模式。查询在大约1/10的时间内完成,没有数千个往返行程。
简洁版本: :Oracle的电线协议(TNS)似乎每个查询结果行中的一个TNS数据包传递数据,并且需要客户在服务器发送下一个数据包之前必须由客户端确认每个数据包。
我找到了一些有关此[此处] [1]的信息(向下滚动直到tnsnames.ora文件中的sdu和tdu参数的部分')。
因此,我的问题是:是否可以控制Oracle驱动程序的行为(我正在使用10.2.0.4.0),以便TNS协议更有效?同样,这是JBOSS部署的非常标准的J2EE应用程序。
非常感谢!
解决方案
调整 SDU 和 tdu tnsnames.ora和listerer.ora中的参数
将批处理大小设置为当前陈述的100。
((OracleStatement)stmt).setRowPrefetch (100);
笔记:
设置预取尺寸可能会影响应用程序的性能。增加预取尺寸将减少获取所有数据所需的往返数量,但会增加内存使用情况。这将取决于查询中列的数量和大小以及预期返回的行数。它还将取决于JDBC客户端计算机的内存和CPU加载。独立客户端应用程序的最佳功能将与重载的应用程序服务器不同。还应考虑网络连接的速度和延迟
可用的连接属性 这里.
也看一下 Oracle UCP 也。
其他提示
尝试增加卫星对象的提取尺寸。
我认为默认值为10,因此您可能会尝试从100开始。
Statement stmt = connection.createStatement(); stmt.setFetchSize(100); ResultSet rs = stmt.executeQuery("SELECT ...");