Explain the SQL syntax example of the most efficient paging query in ORACLE, oraclesql
-- 1: no order by statement. (Most efficient)
-- (After testing, this method has the lowest cost. Only one layer is nested, and the speed is the fastest! Even if the queried data volume is large, it is almost unaffected and the speed is still high !)
SELECT *
FROM (select rownum as rowno, t .*
FROM emp t
WHERE hire_date BETWEEN TO_DATE ('20140901', 'yyyymmdd ')
AND TO_DATE ('20140901', 'yyyymmdd ')
And rownum <= 20) table_alias
WHERE table_alias.rowno> = 10;
-- 2: order by sorting. (Most efficient)
-- (After testing, this method slows down as the query range expands !)
SELECT *
FROM (SELECT tt. *, rownum as rowno
FROM (SELECT t .*
FROM emp t
WHERE hire_date BETWEEN TO_DATE ('20140901', 'yyyymmdd ')
AND TO_DATE ('20140901', 'yyyymmdd ')
Order by create_time DESC, emp_no) tt
Where rownum <= 20) table_alias
WHERE table_alias.rowno> = 10;
========================================================== ========================================================== =
= ============================
========================================================== ========================================================== =
-- 3: no order by statement. (Method 1 is recommended)
-- (This method slows down as the query data size expands !)
SELECT *
FROM (select rownum as rowno, t .*
FROM k_task t
WHERE flight_date BETWEEN TO_DATE ('201312', 'yyyymmdd ')
AND TO_DATE ('20140901', 'yyyymmdd') table_alias
WHERE table_alias.rowno <= 20 AND table_alias.rowno> = 10;
-- TABLE_ALIAS.ROWNO between 10 and 100;
-- 4: there is an order by sorting Statement (method 2 is recommended)
-- (This method slows down as the query range expands !)
SELECT *
FROM (SELECT tt. *, rownum as rowno
FROM (SELECT *
FROM k_task t
WHERE flight_date BETWEEN TO_DATE ('201312', 'yyyymmdd ')
AND TO_DATE ('20140901', 'yyyymmdd ')
Order by fact_up_time, flight_no) tt) table_alias
WHERE table_alias.rowno BETWEEN 10 AND 20;
-- 5 alternative syntax. (Order by Statement)
-- (The syntax style is different from the traditional SQL syntax, which is not easy to read and understand. It is not recommended for standardization and unified standards .)
WITH partdata
(
Select rownum as rowno, tt .*
FROM (SELECT *
FROM k_task t
WHERE flight_date BETWEEN TO_DATE ('201312', 'yyyymmdd ')
AND TO_DATE ('20140901', 'yyyymmdd ')
Order by fact_up_time, flight_no) tt
Where rownum <= 20)
SELECT *
FROM partdata
WHERE rowno> = 10;
-- 6 alternative syntax. (No order by Statement)
WITH partdata
(
Select rownum as rowno, t .*
FROM k_task t
WHERE flight_date BETWEEN TO_DATE ('201312', 'yyyymmdd ')
AND TO_DATE ('20140901', 'yyyymmdd ')
And rownum <= 20)
SELECT *
FROM partdata
WHERE rowno> = 10;
Yangtingkun analysis:
--- From: http://yangtingkun.itpub.net/post/468/100278
Oracle paging query statements can be applied in the format given in this article.
Paging Query format:
SELECT *
FROM (SELECT a. *, ROWNUM rn
FROM (SELECT *
FROM table_name)
Where rownum <= 40)
WHERE rn> = 21
SELECT * FROM TABLE_NAME indicates the original query statement that does not flip pages. ROWNUM <= 40 and RN> = 21 control the range of each page of the paging query.
The paging query statement given above has a high efficiency in most cases. The purpose of paging is to control the size of the output result set and return the result as soon as possible. In the preceding paging query statement, this consideration is mainly reflected in the where rownum <= 40 sentence.
There are two methods to select 21st to 40 records. One is that the second layer of the query in the example above uses ROWNUM <= 40 to control the maximum value, the minimum value is controlled at the outermost layer of the query. The other method is to remove the where rownum <= 40 Statement on the second layer of the query, and control the minimum and maximum paging values at the outermost layer of the query. Here is the query statement:
SELECT *
FROM (SELECT a. *, ROWNUM rn
FROM (SELECT *
FROM table_name))
WHERE rn BETWEEN 21 AND 40
In most cases, the efficiency of the first query is much higher than that of the second query.
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 SQL query condition WHERE ROWNUM <= 40 can be pushed to the inner query by Oracle. In this way, once the query result of Oracle exceeds the ROWNUM limit, the query is terminated and the result is returned.
The second query statement, because the query conditions BETWEEN 21 AND 40 exist on the third layer of the query, oracle cannot push the layer-3 query conditions to the innermost layer (even pushing to the innermost layer makes no sense, because the innermost layer query does not know what RN represents ). Therefore, for the second query statement, the oldest layer of Oracle returns all the data that meets the conditions to the middle layer, and the data that the middle layer returns to the outermost layer is all the data. Data filtering is completed at the outermost layer. Obviously, this efficiency is much lower than the first query.
The query analyzed above is not only a simple query for a single table, but also effective for complex multi-table joint queries or sorting in the innermost query.
The query that contains sorting is not described here, and the next article will explain in detail through examples.
Next we will briefly discuss the situation of Multi-table join.
For the most common equi JOIN queries, CBO generally uses two JOIN Methods: nested loop and hash join (merge join is less efficient than hash join, which is not considered by CBO in general ). Because paging is used, the maximum number of records returned is specified. When the number of returned records exceeds the maximum value, the nested loop can immediately stop and return the results to the intermediate layer, however, hash join must process all result sets (so does merge join ). In most cases, it is highly efficient to select nested loop as the query connection method for paging queries (most of the time when querying by page is the data of the first few pages, the lower the page number, the lower the chance of access ).
Therefore, if you don't mind using HINT in the system, you can rewrite the paging query statement:
SELECT *
FROM (SELECT a. *, ROWNUM rn
FROM (SELECT *
FROM table_name)
Where rownum <= 40)
WHERE rn> = 21