How can I speed up row_number in Oracle?

Posted in Help the coder! on May 6, 2009 at 07:18 IST (about 1 year ago). Subscribe to this post Bookmark and Share Email
Showing comments 1 to 5 of total 5 on page 1 of 1
Post reply
« Previous1Next »

andrews
Rank: 422

I have a SQL query that looks something like this:

SELECT * FROM(
    SELECT
        ...,
        row_number() OVER(ORDER BY ID) rn
    FROM
        ...
) WHERE rn between :start and :end

Essentially, it's the ORDER BY part that's slowing things down. If I were to remove it, the EXPLAIN cost goes down by an order of magnitude (over 1000x). I've tried this:

SELECT 
    ...
FROM
    ...
WHERE
    rownum between :start and :end

But this doesn't give correct results. Is there any easy way to speed this up? Or will I have to spend some more time with the EXPLAIN tool?

Posted by andrews on Wednesday, May 6, 2009, 7:18 am
  • Currently 0.00/5

0 votes

Thank this userFlag this comment

tuxsonna...
Rank: 264

Try indexing the ORDER BY column..

Posted by tuxsonnaire on Wednesday, May 6, 2009, 8:06 am
  • Currently 0.00/5

0 votes

Thank this userFlag this comment

singaniya
Rank: 185

Spend more time with the EXPLAIN PLAN tool. If you see a TABLE SCAN you need to change your query.

Your query makes little sense to me. Querying over a ROWID seems like asking for trouble. There's no relational info in that query. Is it the real query that you're having trouble with or an example that you made up to illustrate your problem?

Posted by singaniya on Wednesday, May 6, 2009, 12:49 pm
  • Currently 0.00/5

0 votes

Thank this userFlag this comment

murthima...
Rank: 175

Looks like a pagination query to me.

From this ASKTOM article (about 90% down the page):

You need to order by something unique for these pagination queries, so that ROW_NUMBER is assigned deterministically to the rows each and every time.

Also your queries are no where near the same so I'm not sure what the benefit of comparing the costs of one to the other is.

Posted by murthimadar on Wednesday, May 6, 2009, 1:15 pm
  • Currently 0.00/5

0 votes

Thank this userFlag this comment

jeffry
Rank: 263

Part of the problem is how big is the 'start' to 'end' span and where they 'live'. Say you have a million rows in the table, and you want rows 567,890 to 567,900 then you are going to have to live with the fact that it is going to need to go through the entire table, sort pretty much all of that by id, and work out what rows fall into that range.

In short, that's a lot of work, which is why the optimizer gives it a high cost.

It is also not something an index can help with much. An index would give the order, but at best, that gives you somewhere to start and then you keep reading on until you get to the 567,900th entry.

If you are showing your end user 10 items at a time, it may be worth actually grabbing the top 100 from the DB, then having the app break that 100 into ten chunks.

Posted by jeffry on Wednesday, May 6, 2009, 5:45 pm
  • Currently 0.00/5

0 votes

Thank this userFlag this comment
Pages: « Previous1Next »

Post your comment (No registration required)

  Add my comment  

TechieDesi Community

Not signed in (Sign-in or Register)
Be a true TechieDesi!
Top 10 Users
Spread the word
Invite your friends
Fan stuff
Help us improve
Need Help
FAQ's
Search tips
Found a bug? Report!
Feeds and letters
Subscribe via RSS
Archives
Subscribe to newsletter
Unsubscribe e-mail
Miscellaneous
Privacy policy
Visit rootnerve
About us
About us
Support the development
Official Blog
Advertise with us
Careers
Copyright (c) 2008, TechieDesi.com. All rights reserved | About us | Do-Not-Disturb registry | Powered by rootnerve | Page rendered in 0.132 seconds