我有两个应用程序:第一个在表 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必须首先按时间顺序对所有相关行进行排序... 所以我的问题是:有没有更好的方法来编写这个查询?
答案 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
使其“更快”的唯一方法是以某种方式进一步限制派生表的大小。