.net Net-OracleDataReader。读取速度非常慢

.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秒才能完成 我甚至取出了循环中的所有代码

我在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在返回少量数据时会花费这么长的时间(而其他工具会在很短的时间内为同一查询返回相同的数据)


与您的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