Reputation: 1387
I have two applications : the first one inserts data in the table MyTable. The second one reads the rows of the table MyTable in chunks : let's say 1000 rows per read. This second app must read the data in chronological order, and use a query similar to :
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
The query works, but it is slow (more than one minute, usually it takes only a few seconds to execute) when a lot of not processed rows (for example 10 millions) are waiting in the table MyTable. I suppose this is normal, because Oracle must first sort all the concerned rows in the chronological order... So my question is : is there a better way to write this query ?
Upvotes: 1
Views: 363
Reputation: 221325
From your execution plan, I'm guessing that your predicate C3 = :C3
is quite costly. You should try to optimise that by avoiding RAW
types. There are several options:
SUBCONTRACTID
NVL(BUSINESSTRANSACTIONID, HEXTORAW('00'))
BUSINESSTRANSACTIONID
and query that using IS NULL
, rather than NVL(...)
ORDER BY timestamp
clause and process records in arbitrary order.Apart from that, your query seems fine.
Also, try applying a /*+FIRST_ROWS(1000)*/
hint, as it seems that this isn't done automatically for some reason in your query, even with ROWNUM
filtering
Upvotes: 1
Reputation: 7932
SELECT * FROM
( SELECT C1, C2
FROM MyTable
WHERE C3 = :C3
AND IsProcessed = 0
ORDER BY Timestamp
) WHERE rownum <= 1000;
Try this query.
Upvotes: 0
Reputation: 9618
You don't really need to define a column for RowNumber:
SELECT C1, C2
FROM (
SELECT C1, C2
FROM MyTable
WHERE C3 = :C3
AND IsProcessed = 0
ORDER BY Timestamp
) temp
WHERE ROWNUM <= 1000
The only way to make it "faster" would be to somehow further restrict the size of the derived table.
Upvotes: 0