1

我有两个应用程序:第一个在MyTable表中插入数据。第二个以块的形式读取MyTable表的行:假设每次读取 1000 行。第二个应用程序必须按时间顺序读取数据,并使用类似于以下内容的查询:

SELECT
    C1,
    C2
FROM
(
    SELECT
        rownum AS RowNumber, 
        C1, 
        C2
    FROM
        MyTable
    WHERE
        C3 = :C3
        AND IsProcessed = 0
    ORDER BY
        Timestamp
) temp 
WHERE 
    temp.RowNumber <= 1000

该查询有效,但当MyTable表中有大量未处理的行(例如 1000 万行)等待时,查询速度很慢(超过一分钟,通常只需要几秒钟即可执行)。我想这是正常的,因为 Oracle 必须首先按时间顺序对所有相关行进行排序......所以我的问题是:有没有更好的方法来编写这个查询?

在此处输入图像描述

4

3 回答 3

1

从您的执行计划来看,我猜您的谓词C3 = :C3非常昂贵。您应该尝试通过避免RAW类型来优化它。有几种选择:

  • 确保你有一个索引SUBCONTRACTID
  • 尝试添加基于函数的索引NVL(BUSINESSTRANSACTIONID, HEXTORAW('00'))
  • 确保您有一个索引BUSINESSTRANSACTIONID并使用IS NULL,而不是查询NVL(...)
  • ORDER BY timestamp如果您可以放宽底层的业务需求,那么删除子句并以任意顺序处理记录当然会有所帮助。

除此之外,您的查询似乎很好。

另外,请尝试应用/*+FIRST_ROWS(1000)*/提示,因为在您的查询中,由于某种原因,这似乎不是自动完成的,即使使用ROWNUM过滤

于 2012-08-13T17:37:17.203 回答
0
SELECT * FROM
  (    SELECT C1, C2
      FROM MyTable
     WHERE C3 = :C3
       AND IsProcessed = 0
     ORDER BY Timestamp
  ) WHERE rownum <= 1000;

试试这个查询。

于 2012-08-13T16:57:19.683 回答
0

您实际上不需要为 RowNumber 定义列:

SELECT C1, C2 
FROM (
   SELECT C1, C2     
   FROM   MyTable
   WHERE  C3 = :C3
      AND IsProcessed = 0
   ORDER BY Timestamp 
   ) temp
WHERE ROWNUM <= 1000

使其“更快”的唯一方法是以某种方式进一步限制派生表的大小。

于 2012-08-13T17:13:03.960 回答