ODP.Net - OracleDataReader.Read非常慢

时间:2013-04-08 16:37:27

标签: .net vb.net oracle odp.net

我在ODP.Net中的OracleDataReader遇到了很多麻烦。基本上,我有一个参数化查询,需要1-5秒才能运行(返回大约450条记录),然后需要60-90秒才能循环(没有代码甚至在循环中运行,字面上迭代记录集并做没有)。

当我从Aqua Data Studio运行它需要1-5秒。 当我从.Net运行它时,cmd.ExecuteReader()返回需要1-5秒。 当我使用OracleDataReader.Read遍历450条记录时,需要60-90秒才能完成。

我甚至拿出了循环中的所有代码并且只有一个空白的“while dr.Read”并且仍然花费60到90秒来循环遍历这450条记录(我使用秒表来获取时间cmd.ExecuteReader然后在空的dr.Read循环周围。)

我尝试过设置FetchSize,它没有帮助(而且,在我的测试用例中只有450条记录)。 我尝试用连接字符串关闭自动调谐功能,性能下降甚至更多。

为什么OracleDataReader.Read在返回少量数据时花了这么长时间(其他工具在很短的时间内为同一个查询返回相同的数据)?

    Using conn As New Oracle.DataAccess.Client.OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings("oracle_dss").ConnectionString)                 
    conn.Open()
    Using cmd As OracleCommand = conn.CreateCommand
        cmd.BindByName = True
        cmd.CommandText = ""  ' removed SQL to make this more readable

        ' Month end
        Dim paramMonthEndDate As OracleParameter = cmd.CreateParameter
        paramMonthEndDate.ParameterName = ":month_end_date"
        paramMonthEndDate.DbType = DbType.Date
        paramMonthEndDate.Value = monthEnd
        cmd.Parameters.Add(paramMonthEndDate)

        Dim sw As New System.Diagnostics.Stopwatch
        sw.Start()

        cmd.FetchSize = 1000
        Dim dr As OracleDataReader = cmd.ExecuteReader
        dr.FetchSize = dr.RowSize * 1000

        sw.Stop()
        Me.Log(String.Format("Month End Query: {0}s", sw.ElapsedMilliseconds / 1000))

        sw.Reset()
        sw.Start()

        While dr.Read

        End While

        sw.Stop()

        Me.Log(String.Format("Month End Query through recordset: {0}s", sw.ElapsedMilliseconds / 1000))

        dr.Close()
            End Using
    conn.Close()
End Using

2 个答案:

答案 0 :(得分:0)

与您的DBA合作并要求他们为独立运行(aqua data studio)和您的odp.net呼叫捕获解释计划,并确认它们实际上是相同的。如果他们不是,那么这可能会解释你的问题。然后,您可以尝试将“enlist = false”添加到您的连接字符串,但更好的是让DBA更新相关表的统计信息,希望能够修复慢速计划。有关详细信息,请参阅https://stackoverflow.com/a/14712992/852208

我遇到了同样的问题,而且当涉及分布式事务时,oracle对执行计划不太乐观。

答案 1 :(得分:0)

可能是我错了,但你实际上是在获取此行中的数据:While dr.Read,而不是在执行阅读器时。所以这可以解释为什么即使没有做任何事,dr.Read也会花费你所有的时间。

我会尝试将您的命令更改为

1)。运行plain sql(不带参数)

2)。使用常规(非绑定变量)参数

运行

3)。如果可能,将sql代码移动到存储过程