使用.Net从Oracle DB读取数据比使用Java快10倍

ant*_*nth 8 .net c# java oracle

我正在使用.Net和Java从Oracle DB中读取1百万条记录.在.Net中,我在Java ojdbc6瘦客户端中使用ODP.Net.在.Net读取数据大约需要10秒钟,在Java中需要将近2分钟.为什么会有这么大的差异?

这是一个代码:

.净:

      try
        {
            DateTime dt1 = DateTime.Now;

            OracleConnection con = new OracleConnection();
            con.ConnectionString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myHost)(PORT=myPort)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=myService)));User Id=myId;Password=myPass;";

            con.Open();
            string cmdQuery = "SELECT * FROM DROPME";

            OracleCommand cmd = new OracleCommand(cmdQuery);
            cmd.Connection = con;
            cmd.CommandType = CommandType.Text;

            int i = 0;
            OracleDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                Object o1 = reader.GetValue(0);
                Object o2 = reader.GetValue(1);
                Object o3 = reader.GetValue(2);
                Object o4 = reader.GetValue(3);
                Object o5 = reader.GetValue(4);
                Object o6 = reader.GetValue(5);
                Object o7 = reader.GetValue(6);                    
                i++;
            }

            DateTime dt2 = DateTime.Now;

            double elapsed = (dt2 - dt1).TotalSeconds;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
Run Code Online (Sandbox Code Playgroud)

Java的:

    try
    {
        long t0 = System.currentTimeMillis();
        oracleDataSource = new OracleDataSource();
        oracleDataSource.setURL("jdbc:oracle:thin:myId/myPass@myHost:myPort:myService");
        Connection connection = oracleDataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement("SELECT * FROM DROPME");
        ResultSet result = statement.executeQuery();
        int i = 0;
        while (result.next())
        {
            result.getObject(1);
            result.getObject(2);
            result.getObject(3);
            result.getObject(4);
            result.getObject(5);
            result.getObject(6);
            result.getObject(7);
            i++;
        }
        long t1 = System.currentTimeMillis();
        long elapsed = (t1 - t0)/1000;
        int t = 0;
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
Run Code Online (Sandbox Code Playgroud)

编辑:setFetchSize()完成了这项工作,谢谢.

PC.*_*PC. 8

默认情况下,在Java中,ResultSets被完全检索并存储在内存中.这对于具有大型ResultSet的查询不利.要使用流式结果,您必须使用:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
Run Code Online (Sandbox Code Playgroud)

我没有比较所花的时间,但我想这会快得多.

  • @PC:我的错误,我误解了你的答案.我以为你在建议驱动程序*一次转移*整个结果集.谢谢你的提示.我忘记了缓冲. (2认同)

Ada*_*ter 6

根据我的经验,Oracle JDBC驱动程序配置不当,无法进行大规模传输.默认情况下,它一次只能通过网络传输10条记录.因此,如果您有1,000,000条记录,则驱动程序将进行100,000次网络访问.

您可以ResultSet使用此代码告知一次要获取的记录数:

result.setFetchSize(1000);
Run Code Online (Sandbox Code Playgroud)

随意尝试不同的尺寸.它至少在我工作过的一个应用程序中大大减少了处理时间(从几分钟到几秒).