我们的SELECT数据库中有一些主要的性能问题。请参阅下面的简单程序和相关代码。
在代码中,ExecuteReader()方法在返回30K记录的查询中大约10秒内执行。迭代读取器需要2分钟(即使我没有将数据泵入任何其他对象)。 30k行数据集的2分钟对我们来说是不可接受的,因为我们期待数百万的数据集。
这里有什么特别突出的吗?希望您使用ODP.NET和PL / SQL的经验可能有所帮助。
create or replace PROCEDURE TRACKING_FETCH (
p_tracking_id IN NUMBER,
p_parent_id IN NUMBER,
p_media_id IN NUMBER,
p_custodian_id IN NUMBER,
p_return_cursor OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_return_cursor FOR
SELECT
*
FROM
tracking
WHERE
(tracking_id = p_tracking_id OR p_tracking_id = 0)
AND (parent_id = p_parent_id OR p_parent_id = 0)
AND (media_id = p_media_id OR p_media_id = 0)
AND (custodian_id = p_custodian_id OR p_custodian_id = 0);
END TRACKING_FETCH;
-
using (DataFactory command
= new DataFactory(dbConnection,
DatabaseType.Oracle,
CommandType.StoredProcedure,
"TRACKING_FETCH"))
{
command.AddInParameter("p_tracking_id", DbType.Int32, trackingid);
command.AddInParameter("p_parent_id", DbType.Int32, parentid);
command.AddInParameter("p_media_id", DbType.Int32, mediaid);
command.AddInParameter("p_custodian_id", DbType.Int32, custodianid);
using (var dr = command.ExecuteReader())
{
while (dr.Read())
{
//Do Things...
}
}
}
非常感谢任何指导。
答案 0 :(得分:4)
值得研究Oracle Wait Interface。 我怀疑网络延迟会让你失望。该过程返回指向结果集的指针。在循环中的某个时刻,我猜你会获取行(即使它们被转储)。
检查v $ sql会告诉您正在完成的提取次数以及处理的行数。将一个除以另一个,你会看到每次获取多少行。如果你正在进行1行/获取甚至10-20,那就是成千上万的网络等待。理想情况下,如果要撤回数百万条记录,每次获取需要数千行,尽管这可能会耗费你的内存。
根据您对数百万行所做的工作,可能值得重新考虑体系结构。例如,如果将它们转储到文件中,则可以在数据库服务器上生成文件,压缩文件,通过网络移动文件,然后解压缩。
答案 1 :(得分:0)
您是否尝试在存储过程上运行EXPLAIN PLAN
?我没有看到您的代码或存储过程出现任何直接问题,但是全表扫描会严重影响查询的执行时间。解释计划会告诉您是否有表扫描,然后您可以调整查询以加快它的速度。
答案 2 :(得分:0)
这不是你的odp.net程序的问题。原因在于SELECT。如果表包含大量记录,则优化程序可以决定运行全表扫描,具体取决于您的参数。检查explain plan语句的运行方式。如果你没有看到任何帮助。尝试trace语句来查看物理读取。