我在 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
与您的 DBA 合作,要求他们为独立运行(aqua data studio)和您的 odp.net 调用获取解释计划,并确认它们实际上是相同的。如果不是,那么这可能可以解释您的问题。然后,您可以尝试将“enlist=false”添加到连接字符串中,但更好的是让 DBA 更新相关表上的统计信息,希望修复缓慢的计划。看https://stackoverflow.com/a/14712992/852208 https://stackoverflow.com/a/14712992/852208了解更多信息。
我也遇到过同样的问题,这归结为当可能涉及分布式事务时,Oracle 对执行计划不太乐观。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)