Oracle database paging principle

rownum of Oracle database

In the Oracle database , the paging method is not as simple as MySql , it needs to rely on rownum to achieve .

 

Wrong understanding:

For paging, we only need to find a way to query from a certain starting line to the ending line, and the logic of paging can be placed in the program.

  1. select*from users where rownum>=3 rownum <=4;

Ha ha! Is it found that there is no result? The reason is very simple. The Oracle mechanism is like this: because the first data row number is 1 and does not meet the >=3 condition, the first row is removed, and the previous second row becomes a new one. The first line of (that is, the line number is not hard-coded, it can be understood as dynamic), and so on, until the last line, the condition cannot be satisfied, so even a single piece of data cannot be found.

    Therefore, we naturally think of the following statement to query the data on page 2 (2 pieces of data per page, the page number starts from 1, so the line number of the starting line is  (page number - 1) * length of each page + 1 = 3 , the end line The line number is  page number * length of each page = 4)

Rownum represents the row number of a record. It is worth noting that it is assigned after each row is obtained . Therefore , it is impossible to specify the range of rownum to obtain paging data in a query statement, and it is necessary to perform paging once. query .

SELECT * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A 
WHERE ROWNUM <= 40
)
WHERE RN >= 21

The innermost query SELECT * FROM TABLE_NAME represents the original query statement without page turning. ROWNUM <= 40 and RN >= 21 control the extent of each page for paginated queries.

The paging query statement given above has high efficiency in most cases. The purpose of paging is to control the size of the output result set and return the results as soon as possible. In the above paging query statement, this consideration is mainly reflected in the sentence WHERE ROWNUM <= 40 .

There are two ways to select the 21st to 40th records. One is to control the maximum value by ROWNUM <= 40 in the second layer of the query as shown in the above example, and control the minimum value in the outermost layer of the query. Another way is to remove the WHERE ROWNUM <= 40 statement in the second layer of the query, and control the minimum and maximum values ​​of paging in the outermost layer of the query. This is, the query statement is as follows:

SELECT * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A 
)
WHERE RN BETWEEN 21 AND 40

Comparing these two writing methods, in most cases, the efficiency of the first query is much higher than that of the second.

This is because in the CBO optimization mode, Oracle can push the outer query conditions to the inner query to improve the execution efficiency of the inner query. For the first query statement, the query condition of the second layer WHERE ROWNUM <= 40 can be pushed into the inner query by Oracle, so that once the result of the Oracle query exceeds the ROWNUM limit, the query is terminated and the result is returned.

For the second query statement, since the query condition BETWEEN 21 AND 40 exists in the third layer of the query, Oracle cannot push the query condition of the third layer to the innermost layer (even pushing it to the innermost layer is meaningless, because The innermost query doesn't know what RN stands for). Therefore, for the second query statement, the innermost layer of Oracle returns all the data that meets the conditions to the middle layer, and the middle layer returns all the data to the outermost layer. The filtering of data is done in the outermost layer, which is obviously much less efficient than the first query.

The query analyzed above is not only a simple query for a single table, but also effective for the case where the innermost query is a complex multi-table union query or the innermost query contains sorting.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326227838&siteId=291194637