.net Net-OracleDataReader。读取速度非常慢
我在ODP.Net中使用OracleDataReader时遇到了很多问题。基本上,我有一个参数化的查询,运行需要1-5秒(返回大约450条记录),然后循环需要60-90秒(循环中甚至没有代码运行,实际上是在记录集上迭代,什么也不做) 当我从Aqua Data Studio运行它时,需要1-5秒。 当我从.Net运行它时,cmd.ExecuteReader()需要1-5秒才能返回。 当我用OracleDataReader循环读取450条记录时,需要60-90秒才能完成 我甚至取出了循环中的所有代码,只有一个空白的“While dr.Read”,但仍然需要60到90秒来循环这450条记录(我使用秒表来获取cmd.ExecuteReader的时间,然后绕过空的dr.Read循环) 我试过设置FetchSize,但没有帮助(而且,在我的测试用例中只有450条记录)。 我曾尝试过用连接字符串关闭自动调谐,这会进一步降低性能 为什么OracleDataReader.Read在返回少量数据时会花费这么长的时间(而其他工具会在很短的时间内为同一查询返回相同的数据).net Net-OracleDataReader。读取速度非常慢,.net,vb.net,oracle,odp.net,.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循环读取450条记录时,需要60-90秒才能完成 我甚至取出了循环中的所有代码
与您的DBA合作,让他们为单机运行(aqua data studio)和odp.net调用捕获一个解释计划,并确认它们实际上是相同的。如果他们不是,那么这可能会解释你的问题。然后,您可以尝试向连接字符串中添加“inclist=false”,但最好让DBA更新相关表的统计信息,希望能够修复这个缓慢的计划。有关更多信息,请参阅
我也遇到过同样的问题,这归结于oracle在可能涉及分布式事务时对执行计划不太乐观。可能我错了,但您实际上是在dr.Read时获取这一行数据的:
,而不是在执行读卡器时。因此,这可以解释为什么即使什么都不做,dr.Read
也会占用你所有的时间
我会把你的命令改成
1) 。运行普通sql(不带参数)
2) 。使用常规(非绑定变量)参数运行
3) 。如果可能的话,将sql代码移动到存储过程中您能显示您的代码吗。。也许您正在做一些打开和关闭连接的事情,基本上有太多的往返,但是如果没有看到任何现有代码,就无法判断。您还查看了查询是否命中索引了吗?如果您要查询的表中有索引,请让我获取代码,然后更新问题。它被编入索引。。它在Aqua Data Studio(第三方查询实用程序)中运行到完成,所有结果在几秒钟内返回。我认为如果索引不起作用,也会相当慢。你确定服务器的响应时间吗?oracle配置可能也有问题。SQL datareader速度更快,但这是一个很大的区别。我用秒表计时了.Net代码的每一行,我刚刚读取了第三方实用程序的执行时间(然后滚动其数据网格以验证所有数据是否存在)。我会去看看他们是否能在这两个方面都获得捕获(另外,我以前在今天的连接字符串中添加了ENSTER=false)。什么样的例子会让Oracle不那么乐观?我很好奇我是否在做一些我没有意识到的事情来触发它。显然(从链接文章的帖子中),仅仅拥有分布式连接的可能性就足够了(这是连接的默认设置)。在我的例子中,我实际上是在TransactionScope的环境中做事情,但论坛上的oracle专家表示,这甚至不是一个要求。一旦我意识到计划不同,更新统计数据就解决了这个问题。也许是运气吧。关键是oracle为一个连接计算的执行计划可能不同于另一个连接,因此在odp.net之外运行原始查询不一定可以原谅DB。
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