什么是StringBuilder的可能的原因和ResultSet性能问题

我通过在Java中的ResultSet循环; 这对于测试目的是返回约30行,每行17列(所有字符串数据)。 我手动建立一个XML字符串了使用StringBuilder的它从字面上以约36秒钟的循环来完成这些迭代的结果。

注:我知道这是不是去获得XML列的数据库,甚至让XML列的ResultSet的最佳途径的最好办法 - 但是这我好奇的性能下降而不管。

更新:根据答复迄今我必须解决以下问题:运行查询是不到一秒的时间,而我做了System.currentTimeMillis的()前,我的代码每节过后以缩小下来。 36秒完全下面的代码中。

ResultSetMetaData rsmeta = rset.getMetaData(); StringBuilder resultBuilder = new StringBuilder(); resultBuilder.append("<?xml version=\"1.0\" ?><ROWSET>"); if(numColumns != 0){ while (rset.next()) { resultBuilder.append("<ROW>"); for (int i = 0; i <= numColumns -1;i++) { columnName = rsmeta.getColumnName(i+1); resultBuilder.append("<"); resultBuilder.append(columnName); resultBuilder.append(">"); resultBuilder.append(rset.getString(i+1)); resultBuilder.append("</"); resultBuilder.append(columnName); resultBuilder.append(">"); } resultBuilder.append("</ROW>"); numRows += 1; } } else { stmt.close(); wsConn.close(); return "No Results"; }

更新:由于我收到的建议-此代码大致需要的时间是相同的给予或采取半秒。

StringBuilder resultBuilder = new StringBuilder(); resultBuilder.append("<?xml version=\"1.0\" ?><ROWSET>"); if(numColumns != 0){ while (rset.next()) { resultBuilder.append("<ROW>"); for (int i = 0; i <= numColumns -1;i++) { //columnName = rsmeta.getColumnName(i+1); resultBuilder.append("<"); resultBuilder.append("TestColumnName"); resultBuilder.append(">"); //resultBuilder.append(rset.getString(i+1)); resultBuilder.append("TestData"); resultBuilder.append("</"); resultBuilder.append("TestColumnName"); resultBuilder.append(">"); } resultBuilder.append("</ROW>"); numRows += 1; } } else { stmt.close(); wsConn.close(); return "No Results"; }

最后的测试,我已经做了消除一切是与迭代现实一些替换,而测试(160,最大行由小测试我以前做过返回)。 现在的问题是,可能是什么有关,导致这么慢下来这个结果集。

while (numRows <= 160) { // same as above }

更新:作为建议,我将关闭这个问题作为标题不反映方向的问题了。

--------------解决方案-------------

我很怀疑StringBuilder是罪魁祸首这里。 Java使用它广泛,我已经用它广泛,我已经改写为我整理的,JVM自身,基本上它总是能够通过亿万每秒吃个字符。

我觉得你的麻烦来自于数据库访问本身。 当您运行一个查询并获得一个ResultSet ,这并不意味着所有的数据已获得和内部改造成一个易于管理的内存中表示。 根据数据库实现(和它的JDBC驱动),该ResultSet可以是一个数字的结果,这是动态地取出时的一个承诺ResultSet.next()ResultSet.getString()方法被调用。

简单地尝试探索的结果,要求所有的next()getString()但没有存储所获得的数据在你StringBuilder 如果它仍然需要36秒然后StringBuilder是无辜的(我强烈相信这是)。

我觉得你的注2说话本身。

时间是不输于StringBuilder的,但别的地方...



columnName = rsmeta.getColumnName(i+1);


读取的元数据可能是很慢的,取决于实现。 你可以看他们只有一次对所有结果集,并重新使用他们在循环。



UPDATE

从你的最后一次更新,StringBuilder的是出于关心,而问题是与ResultSet。 我觉得这个问题称号,并给予所有答案,不同步与您当前的当务之急。
我建议关闭这个问题,并为新的当务之急打开一个新 :-)

我强烈怀疑StringBuilder的是你的瓶颈,相较于采取从数据库中访问和检索数据的时间。 事实上,优化简单的字符串连接没有显著改变运行时证实了这一点。

你需要看看优化你如何访问数据库 - 到数据库更快的连接,压缩连接,等等。

不过,我可以提供一个微优化代码:不是追加单字符的字符串,如“<”,追加一个字符,如“<”。 然而,这不应该让太多什么区别。

实际上读取的结果集getColumnName(信息),下一个()和getValue()往往需要更多的时间比获取的结果摆在首位。 这对于非滚动的结果集尤其如此。

StringBuilder的指数分配内存(newSize =因子* oldSize),所以你做的越多,就越需要重新分配。

要真正测试这一点,只需更换RSETrsmeta与具有相同的方法虚拟对象:让下一个()返回true的行的真实的数量,并有其他方法返回现实长度的字符串。

问题是,该ResultSet具有到数据库的持久连接,并得到时其所谓的详细信息。 我建议你寻找到一个CachedRowSet (这里的javadoc)。 它会立即拉下所有的数据和行为完全像一个ResultSet ,否则。 然后,您可以关闭数据库连接,然后开始分析你的数据。 我建议尝试这一点,看看它是否能够提高你的过程。

检查你是如何得到的结果集返回。 有在声明中的方法,允许您更改ResultSet中拉数据。

特别是,看

  • 声明#的setFetchSize
  • 声明#setFetchDirection

我同意StringBuilder的可能不是实时的下沉在这里。 然而,StringBuffer的可能会略有限制的,因为它最终不得不分配额外的空间作为缓存的增长(和超过它的默认大小)。 这个建议解决你的问题,但是,我怀疑他们会解决你的问题。

祝你好运

试着用罐头数据代替各种调用。 例如,有人曾建议,在访问元数据是罪魁祸首。 尝试更换:

columnName = rsmeta.getColumnName(i+1);

有:

columnName = "Column" + i;

其中i是一个int您完成整个循环的循环和增量之前设置为0。

昨天我有类似的问题:查询一个Microsoft SQL Server 10为约170万条记录和读取值大约花了50分钟。 本次变动后; 约80数秒

我的问题是使用JDBC驱动程序:唯一的变化是打算从com.microsoft.sqlserver.jdbc 1.2版驱动程序net.sourceforge.jtds版本1.2.2驱动程序...

分类:java的 时间:2015-03-15 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.700 (s). 10 q(s)