.net 为什么OracleDataAdapter.Fill()非常慢?
我正在使用一个非常复杂的查询从我们的一个账单数据库中检索一些数据 我遇到了一个问题,在使用SQL Developer执行查询时,查询似乎完成得相当快,但在使用OracleDataAdapter.Fill方法时,查询似乎从未完成 我只尝试读取大约1000行,查询在SQLDeveloper中完成大约20秒 是什么导致了如此巨大的性能差异?我有很多其他的查询,它们使用相同的函数快速运行 下面是我用来执行查询的代码:.net 为什么OracleDataAdapter.Fill()非常慢?,.net,sql,oracle,ado.net,oracleclient,.net,Sql,Oracle,Ado.net,Oracleclient,我正在使用一个非常复杂的查询从我们的一个账单数据库中检索一些数据 我遇到了一个问题,在使用SQL Developer执行查询时,查询似乎完成得相当快,但在使用OracleDataAdapter.Fill方法时,查询似乎从未完成 我只尝试读取大约1000行,查询在SQLDeveloper中完成大约20秒 是什么导致了如此巨大的性能差异?我有很多其他的查询,它们使用相同的函数快速运行 下面是我用来执行查询的代码: using Oracle.DataAccess.Client; ... publi
using Oracle.DataAccess.Client;
...
public DataTable ExecuteExternalQuery(string connectionString, string providerName, string queryText)
{
DbConnection connection = null;
DbCommand selectCommand = null;
DbDataAdapter adapter = null;
switch (providerName)
{
case "System.Data.OracleClient":
case "Oracle.DataAccess.Client":
connection = new OracleConnection(connectionString);
selectCommand = connection.CreateCommand();
adapter = new OracleDataAdapter((OracleCommand)selectCommand);
break;
...
}
DataTable table = null;
try
{
connection.Open();
selectCommand.CommandText = queryText;
selectCommand.CommandTimeout = 300000;
selectCommand.CommandType = CommandType.Text;
table = new DataTable("result");
table.Locale = CultureInfo.CurrentCulture;
adapter.Fill(table);
}
finally
{
adapter.Dispose();
if (connection.State != ConnectionState.Closed)
{
connection.Close();
}
}
return table;
}
下面是我正在使用的SQL的概述:
with
trouble_calls as
(
select
work_order_number,
account_number,
date_entered
from
work_orders
where
date_entered >= sysdate - (15 + 31) -- Use the index to limit the number of rows scanned
and
wo_status not in ('Cancelled')
and
wo_type = 'Trouble Call'
)
select
account_number,
work_order_number,
date_entered
from
trouble_calls wo
where
wo.icoms_date >= sysdate - 15
and
(
select
count(*)
from
trouble_calls repeat
where
wo.account_number = repeat.account_number
and
wo.work_order_number <> repeat.work_order_number
and
wo.date_entered - repeat.date_entered between 0 and 30
) >= 1
使用Microsoft Data Provider for Oracle和本机Oracle数据提供程序之间存在已知的性能差异 你两个都试过了吗 您试图通过此查询实现什么?忘了技术方面的东西,仅仅是它的目标。也许有一个调子可以用于您的查询
您是否尝试过使用探查器查看它被卡住的地方?我认为Oracle查询返回的区域性和日期是不同的,这就是应用程序需要花费大量时间进行解析的地方 此代码对我有帮助,请尝试:
using (OracleConnection conn = new OracleConnection())
{
OracleCommand comm = new OracleCommand();
comm.Connection = conn;
comm.FetchSize = comm.FetchSize * 16;
comm.CommandText = "select * from some_table";
try
{
conn.Open();
OracleDataAdapter adap = new OracleDataAdapter(comm);
System.Data.DataTable dt = new System.Data.DataTable();
adap.Fill(dt);
}
finally
{
conn.Close();
}
}
trik与从8到64的try值一致,以找到最适合您的案例:
comm.FetchSize = comm.FetchSize * 16;
更新:
下面是一个改进的代码:
OracleConnection myConnection = new OracleConnection(myConnectionString);
OracleCommand myCommand = new OracleCommand(mySelectQuery, myConnection);
myConnection.Open();
using (OracleDataReader reader = myCommand.ExecuteReader(CommandBehavior.CloseConnection))
{
// here goes the trick
// lets get 1000 rows on each round trip
reader.FetchSize = reader.RowSize * 1000;
while (reader.Read())
{
// reads the records normally
}
}// close and dispose stuff here
从开始,我在使用Oracle中的Oracle.DataAccess.dll事实上,Systm.Data.OracleClient在.NET 4中已被弃用-因此,在顶部,我使用了Oracle.DataAccess.Client;是的,20秒比300秒低。。。不幸的是,我们谈论的是一个具有数千万行的表……当然,它需要时间来执行=使用其他查询使用相同的代码对相同的数据库服务器进行PHITING运行得非常快。我让这个20秒的查询在晚上运行。我会调查这件事的…不要冒险。删除table.Locale调用没有效果。我在SQL Server上也遇到过类似的问题,但没有令人满意的解决方案。如果您可以运行数据包跟踪或应用程序跟踪来比较这两个查询,这可能会对这一问题有所帮助。解释如下: