This query is generated from a very long dynamic sequel stored procedure — the procedure returns the requested number of records starting at a given index to be displayed in a Telerik Radgrid, effectively handling paging. A simplified version of the stored proc’s output:
SELECT r.* FROM (
SELECT ROW_NUMBER() OVER(ORDER BY InventoryId DESC) as row,
v.* FROM vInventorySearch v
) as R WHERE [ROW] BETWEEN 1 AND 10
When the “BETWEEN” clause is between 1 and 10, it runs in a fraction of a second, but if it’s between something like 10000 and 1010 it takes almost a full minute to execute.
I feel like I may be missing something fundamental here, but it seems to me that it shouldn’t matter which 10 records I’m retrieving, it should take the same amount of time.
Thanks for any input, I’m looking forward to being embarrassed!
Solution, courtesy Martin Smith (below) :
SELECT r.*, inv.* FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY InventoryId DESC) as row, v.InventoryID
FROM vInventorySearch v
WHERE 1=1
) as R
inner join vInventory inv on r.InventoryID = inv.InventoryID
WHERE [ROW] BETWEEN 10001 AND 10010
Thanks for your help!
Paginating by
ROW_NUMBERcan indeed be pretty inefficient for higher row numbers.Sometimes it is better to break it up a bit and have the
ROW_NUMBERquery on a narrow index to retrieve the matching PKs with a join back onto the base table to retrieve the missing columns.