迭代Java RecordSet时滞后

时间:2018-03-22 14:20:34

标签: java sql sql-server recordset

我有CallableStatement,我用它来使用存储过程从DB中检索大约500条记录。

我平均返回结果300毫秒,但处理所有这些记录大约需要1-2秒。

CallableStatement a = connection.prepareCall("SP_HERE",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        a.setFetchSize(4000);

比:(我收到的回复很少)

        boolean hadResults = a.execute();
        while (hadResults) {

            ResultSet rs = a.getResultSet();

            List<Map<String,DBInput>> tmpDB = processResultSet(rs);
            ...
            hadResults = a.getMoreResults();    

        }   

滞后部分在这里:

private List<Map<String,DBInput>> processResultSet (ResultSet rs){

    List<Map<String,DBInput>> dbIn = new ArrayList<>();

    try {
        while (rs.next()){

            ResultSetMetaData rsmd = rs.getMetaData();

            int columnCount = rsmd.getColumnCount();

            Map<String,DBInput> map = new HashMap<>();

            for (int i = 1; i <= columnCount; i++) {

                String columnName = rsmd.getColumnLabel(i);

                DBInput tmp = new DBInput();

                int columnType = rsmd.getColumnType(i);

                 Object value = null;
                 int type = OEMIO.NULL;
                 long timeBefore = System.currentTimeMillis(); 
                 switch (columnType){

                 case VARCHAR:

                     value = rs.getString(i);
                     type = OEMIO.STRING;
                     break;

                 case CHAR:

                     value = rs.getString(i);
                     type = OEMIO.STRING;
                     break;

                 case INTEGER:

                     value = rs.getInt(i);
                     type = OEMIO.INTEGER;
                     break;

                 case DECIMAL:

                     value = rs.getBigDecimal(i);

                     if (value != null) value = ((BigDecimal)value).doubleValue();
                     type = OEMIO.DOUBLE;
                     break;

                 case TIMESTAMP:

                    if (rs.getTimestamp(i) == null) break;

                     value = rs.getTimestamp(i).toString();

                     if(rs.getTimestamp(i).toString().contains(" ")){

                         value = rs.getTimestamp(i).toString().replace(" ", "T") + "Z";
                     }
                     type = OEMIO.DATE;
                     break;

                 case DATE:

                     if (rs.getDate(i) == null) break;

                     value = rs.getDate(i).toString();

                     if(rs.getDate(i).toString().contains(" ")){

                         value = rs.getDate(i).toString().replace(" ", "T") + "Z";
                     }

                     type = OEMIO.DATE;
                     break; 

                case BIT:

                     value = rs.getBoolean(i);
                     type = OEMIO.BOOLEAN;
                     break; 

                default:

                    value = "NO TYPE IDENTIFIED";
                    type=-1;
                 }
                long timeAfter = System.currentTimeMillis();
                long diff = timeAfter-timeBefore;
                if (diff > 10) {

                    logger.debug("Column: " + diff + "ms" + "  " + columnType + "  index id: " + i);
                    OrdersManagerThread.type.add(columnType+"");
                }

                 tmp.setDbInput(columnName);
                 tmp.setType(type);
                 tmp.setValue(value);
                 map.put(columnName, tmp);

            }

            dbIn.add(map);

        }
    } catch (SQLException e) {

        logger.error("Error parsing ResultSet: " + e.getMessage());

    }finally{

        rs.close();
    }

    return dbIn;
}

出于某些原因,我不明白为什么有时候,从RecordSet获取结果时,switch case是否会滞后? 这是测试版:

列:170ms 12索引id:34

列:165ms 12索引id:50

列:142ms 12索引id:55

列:171ms 12索引id:4

列:180ms 12索引id:76

列:151ms 12索引ID:68

列:80ms 12索引id:62

列:90ms 3索引id:16

列:79ms 12索引id:9

列:89ms 12索引id:4

列:85ms 3索引id:15

列:85ms 1索引id:10

列:101ms 12索引id:4

什么可能导致这些滞后?

由于

更新:

添加

    **Thread.sleep (10000);**
    boolean hadResults = a.execute();
    while (hadResults) {

        ResultSet rs = a.getResultSet();

        List<Map<String,DBInput>> tmpDB = processResultSet(rs);
        ...
        hadResults = a.getMoreResults();    

    }

&#34;修正&#34;问题。什么可能导致这种情况发生?或者它是否给出任何解决方向?

1 个答案:

答案 0 :(得分:0)

您的抓取尺寸看起来很小。这可能会导致额外的往返服务器。尝试增加它。如果可以的话,我会从大到足以容纳整个结果集的东西开始,然后退回以找到内存和I / O之间的快乐平衡