2

在我们的一个数据库中进行 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...
              }
       }
}

任何指导将不胜感激。

4

3 回答 3

4

值得在 Oracle 等待接口上学习。我怀疑网络延迟正在杀死你。该过程正在返回一个指向结果集的指针。在您的循环中的某个时刻,我猜您正在获取行(即使它们被转储)。

检查 v$sql 将告诉您正在完成多少次提取以及处理了多少行。一个一个除,你会看到每次提取有多少行。如果您正在执行 1 行/提取甚至 10-20 次,则需要数以千计的网络等待。如果要拉回数百万条记录,则理想情况下每次提取需要数千行,尽管这可能会占用您的内存。

根据您对数百万行所做的工作,可能值得重新考虑架构。例如,如果它们被转储到文件中,那么可能会在数据库服务器上生成文件,压缩它,通过网络移动文件,然后解压缩。

于 2009-12-09T02:09:35.723 回答
0

您是否尝试过EXPLAIN PLAN在存储过程上运行?我没有看到您的代码或存储过程有任何直接问题,但全表扫描会严重缩短查询的执行时间。解释计划会告诉您是否有表扫描,然后您可以调整查询以加快速度。

于 2009-12-08T22:05:02.347 回答
0

这不是您的 odp.net 程序的问题。原因在于SELECT。如果表包含大量记录,则可能是优化器决定运行全表扫描,具体取决于您的参数。用解释计划检查语句如何运行。如果您没有看到任何帮助。尝试跟踪语句以查看物理读取。

于 2009-12-09T14:06:05.463 回答