有没有从Java应用程序解决Oracle TNS效率低下(多次往返、延迟)的解决方案?
我看到的是一个非常慢的SQL查询(源于使用JBoss5.1中部署的Hibernate的Java应用程序)。这个特定的查询返回了大约10K条记录,但仍然需要40秒或更长时间 最后我用数据库嗅探了流量(wireshark有一个TNS剖析器),发现了一些意想不到的东西。当数据来自服务器时,每个结果行都在其自己的TNS数据包中。此外,在从数据库发送下一个TNS数据包之前,客户端(即应用程序服务器)确认每个TNS数据包。对于10K记录,有10K往返才能获取数据包并确认它。对性能的影响是巨大的 这是非常低效的。TCP允许更大的数据包,并有许多机制(滑动窗口、延迟确认)来减少延迟和增加吞吐量。然而,在这种情况下,是TNS协议添加了自己的协商 如果我从Oracle的SQL开发人员那里运行相同的查询,我看不到这种模式。查询大约在1/10的时间内完成,无需数千次往返 简短版本:Oracle的有线协议(TNS)似乎在每个查询结果行的一个TNS数据包中传递数据,并要求客户端在服务器发送下一个数据包之前确认每个数据包 我在这里[1]找到了一些相关信息(向下滚动到“tnsnames.ora文件中的SDU和TDU参数”部分) 因此我的问题是:是否有可能控制Oracle驱动程序的行为(我使用的是10.2.0.4.0),从而使TNS协议更高效?同样,这是部署在JBoss中的一个非常标准的J2EE应用程序有没有从Java应用程序解决Oracle TNS效率低下(多次往返、延迟)的解决方案?,oracle,performance,tns,Oracle,Performance,Tns,我看到的是一个非常慢的SQL查询(源于使用JBoss5.1中部署的Hibernate的Java应用程序)。这个特定的查询返回了大约10K条记录,但仍然需要40秒或更长时间 最后我用数据库嗅探了流量(wireshark有一个TNS剖析器),发现了一些意想不到的东西。当数据来自服务器时,每个结果行都在其自己的TNS数据包中。此外,在从数据库发送下一个TNS数据包之前,客户端(即应用程序服务器)确认每个TNS数据包。对于10K记录,有10K往返才能获取数据包并确认它。对性能的影响是巨大的 这是非常低效
非常感谢 尝试增加sament对象的获取大小 我认为默认值是10,因此您可以尝试从100开始 Statement stmt = connection.createStatement(); stmt.setFetchSize(100); ResultSet rs = stmt.executeQuery("SELECT ..."); 语句stmt=connection.createStatement(); stmt.setFetchSize(100); 结果集rs=stmt.executeQuery(“选择…”); 调整tnsnames.ora和listener.ora中的和参数 将当前状态的批次大小设置为100
((OracleStatement)stmt).setRowPrefetch (100);
注:
设置预取大小可能会影响
应用程序的性能。
增加预取大小将
减少往返的次数
需要获取所有数据,但将
提高内存使用率。这将
取决于系统的数量和大小
查询中的列以及
应返回的行。会的
也取决于内存和CPU
加载JDBC客户机。
独立客户端的最佳配置
应用程序将不同于
负载沉重的应用服务器。这个
网络的速度和延迟
还应考虑连接。还应考虑连接
(来自)
可用的连接属性
也请看一看。谢谢,在谷歌搜索行预取之后,我发现下面的“标准JDBC一次只接收一行结果集,并且每一行都需要到数据库的往返”,这解释了我所看到的情况。隐马尔可夫模型。。是否可以在数据源级别进行设置?处的参数列表不包含预取设置。同时,我在处找到了一个驱动程序属性(defaultRowPrefetch),您是否正在使用UCP?通过填充TCP数据包,增加获取大小确实改善了情况。嘿,感谢您的深入提问,并向有类似情况的人提供一些提示。。投赞成票。。