需要一些建议来优化Oracle查询

时间:2012-08-13 16:51:38

标签: sql oracle query-optimization

我有两个应用程序:第一个在表 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

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

enter image description here

3 个答案:

答案 0 :(得分:1)

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

  • 确保您拥有SUBCONTRACTID
  • 的索引
  • 尝试在NVL(BUSINESSTRANSACTIONID, HEXTORAW('00'))
  • 上添加基于函数的索引
  • 确保您拥有BUSINESSTRANSACTIONID的索引并使用IS NULL而非NVL(...)
  • 进行查询
  • 如果您可以放宽基本业务需求,那么当然有助于删除ORDER BY timestamp子句并按任意顺序处理记录。

除此之外,您的查询似乎没问题。

此外,请尝试应用/*+FIRST_ROWS(1000)*/提示,因为即使使用ROWNUM过滤

,您的查询似乎也无法自动完成此操作

答案 1 :(得分:0)

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

尝试此查询。

答案 2 :(得分:0)

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

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

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