Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for pagination in Oracle?

Problem: I need write stored procedure(s) that will return result set of a single page of rows and the number of total rows.

Solution A: I create two stored procedures, one that returns a results set of a single page and another that returns a scalar -- total rows. The Explain Plan says the first sproc has a cost of 9 and the second has a cost of 3.

SELECT  * FROM    ( SELECT ROW_NUMBER() OVER ( ORDER BY D.ID DESC ) AS RowNum, ...         ) AS PageResult WHERE   RowNum >= @from     AND RowNum < @to ORDER BY RowNum  SELECT  COUNT(*) FROM    ... 

Solution B: I put everything in a single sproc, by adding the same TotalRows number to every row in the result set. This solution feel hackish, but has a cost of 9 and only one sproc, so I'm inclined to use this solution.

SELECT *  FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY D.ID DESC  ) RowNum, COUNT(*) OVER () TotalRows, WHERE RowNum >= from         AND RowNum < to ORDER BY RowNum; 

Is there a best-practice for pagination in Oracle? Which of the aforementioned solutions is most used in practice? Is any of them considered just plain wrong? Note that my DB is and will stay relatively small (less than 10GB).

I'm using Oracle 11g and the latest ODP.NET with VS2010 SP1 and Entity Framework 4.4. I need the final solution to work within the EF 4.4. I'm sure there are probably better methods out there for pagination in general, but I need them working with EF.

like image 325
Howie Avatar asked Dec 06 '12 06:12

Howie


People also ask

What is Oracle pagination query?

Pagination is common in Web-based applications: The user inputs a set of criteria, which runs a query and then lets the user click the Previous and Next buttons to page through the result set. To achieve this paging functionality, the application needs to be able to get a certain set of rows from the query.

Does pagination improve performance SQL?

Thanks to pagination, we can split our large dataset into chunks ( or pages ) that we can gradually fetch and display to the user, thus reducing the load on the database. Pagination also solves a lot of performance issues both on the client and server-side!

Why Rowid is faster in Oracle?

ROWID is the physical location of a row. Consequently it is the fastest way of locating a row, faster even than a primary key lookup. So it can be useful in certain types of transaction where we select some rows, store their ROWIDs and then later on use the ROWIDs in where clauses for DML against those same rows.


2 Answers

If you're already using analytics (ROW_NUMBER() OVER ...) then adding another analytic function on the same partitioning will add a negligible cost to the query.

On the other hand, there are many other ways to do pagination, one of them using rownum:

SELECT *    FROM (SELECT A.*, rownum rn           FROM (SELECT *                   FROM your_table                  ORDER BY col) A          WHERE rownum <= :Y)  WHERE rn >= :X 

This method will be superior if you have an appropriate index on the ordering column. In this case, it might be more efficient to use two queries (one for the total number of rows, one for the result).

Both methods are appropriate but in general if you want both the number of rows and a pagination set then using analytics is more efficient because you only query the rows once.

like image 157
Vincent Malgrat Avatar answered Oct 04 '22 04:10

Vincent Malgrat


This may help:

   SELECT * FROM       ( SELECT deptno, ename, sal, ROW_NUMBER() OVER (ORDER BY ename) Row_Num FROM emp)      WHERE Row_Num BETWEEN 5 and 10; 
like image 33
Art Avatar answered Oct 04 '22 03:10

Art