views:

167

answers:

3

Hi,

This is a followup on the question: http://stackoverflow.com/questions/1014526/asp-net-next-previous-buttons-to-display-single-row-in-a-form

As it says on the page above, theres a previous/next button on the page, that retrieves a single row one at a time.

Totally there's ~500,000 rows.

When I "page" through each subscribtion number, the form gets filled with subscriber details. What approach should I use on the SQL server?

Using the ROW_NUMBER() function seems a bit overkill as it has to number all ~500.000 rows (I guess?), so what other possible solutions are there?

Thanks in advance!

+2  A: 

ROW_NUMBER() is probably your best choice.

From this MSDN article: http://msdn.microsoft.com/en-us/library/ms186734.aspx

WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;

And just subsititute 50 and 60 with a parameter for the row number you want.

AndyMcKenna
Already doing that, and it's rather slow. I was curious if there is another approach.
Tommy Jakobsen
@Tommy Jakobsen: What indexes do you have on table SalesOrderHeader ?
Mitch Wheat
If I'm using ROW_NUMBER(), I don't need an index, do I?
Tommy Jakobsen
@Tommy: WHAT?! Indexes are your friend. Please use them.
Eric
In the Sales example above, what would you index on to speed things up?
Tommy Jakobsen
@Tommy: Clustered on SalesOrderID, Nonclustered non-unique on OrderDate
Eric
A: 

There are two potential workarounds (for this purpose, using a start of 201, pages of 100):

SQL

SELECT TOP 100 * FROM MyTable WHERE ID > 200 ORDER BY ID

LINQ to SQL

var MyRows = (from t in db.Table 
              order by t.ID ascending
              select t).Skip(200).Take(100)

If your ID field has a clustered index, use the former. If not, both of these will take the same amount of time (LINQ returns 500,000 rows, then skips, then takes).

If you're sorting by something that's NOT ID and you have it indexed, use ROW_NUMBER().

Edit: Because the OP isn't sorting by ID, the only solution is ROW_NUMBER(), which is the clause that I put at the end there.

In this case, the table isn't indexed, so please see here for ideas on how to index to improve query performance.

Eric
I'm not sorting on ID. So ROW_NUMBER is the only solution left?
Tommy Jakobsen
@Eric: Your first example assumes that the records will be sorted by ID and that there will be no gaps in the numbering. Your second example will usually be translated into a ROW_NUMBER() query by LINQ-to-SQL anyway.
LukeH
A: 

Tommy, if your user has time to page through 500,000 rows at one page per row, then he/she is unique.

I guess what I am saying here is that you may be able to provide a better UX. When - Too many pages? Build a search feature.

Raj More
There is already a search feature. It's stupid that theres a "single-row paging function" for 500.000 rows yes, but thats how my customer wants it :)
Tommy Jakobsen
Sometimes paging is still necessary. See: http://stackoverflow.com/questions
Eric
Is that the correct link, Eric?
Tommy Jakobsen
@Tommy: Yeah, there's paging through all of the questions on StackOverflow. It's around 50,000 rows, and paging is still necessary.
Eric
@Eric - I agree paging is necessary and almost all sites provide paging in some form. I was talking about UX so @Tommy did not miss out on a trick to wow his customer by making things easy(ier) for them. In all of my years of Googling for things, I have _never_ gone beyond page 3. I just revise/refine my search.
Raj More