Differences and linkages between Row_number and RowNum in Oracle (translation)

Source: Internet
Author: User
Tags create index

Http://www.tuicool.com/articles/bI3IBv

Attached problem: There is one SQL statement below:

Select  *from    (        Select  t.*, Row_number () over (frommytable t)WHERE RN between:  And:end     

The ORDER BY statement in SQL greatly reduces the processing speed, and if the order by is removed, the corresponding execution plan is greatly improved. If you switch to the following SQL:

SELECT  t.*, Row_number () over (byID) rnfrom    mytable tWHERE rownum between: and:end
             

Obviously, this SQL is wrong and cannot query the correct data information at all. Is there any other way to improve the query speed?
In view of the above problems, it is necessary to understand the difference between row_number and rownum, and how to use this information.

First look at how RowNum works, according to Oracle's official documentation:
If the rownum is larger than the comparison, this comparison will return false directly. For example, the following SQL statement will not return any data information:

SELECT  *from    employeesWHERE   1  

In the query, the first hit data is given a pseudo-column rownum of 1, then this condition is false. Second hit data because the first false will be the first data again, then the value is still assigned to 1, indicating that the condition is still false. All subsequent data will repeat this logic, and the last piece of data is not returned.

This is why the previous 2nd query should be converted to the following SQL statement:

Select  *from    (        Select  as RN        by paginator, id)WHERE rn between: and: End      

Next, you need to create some temporary data tables to see the execution performance of this SQL statement, we will create a temporary table, append the index, then populate the data, and finally analyze the query information for this SQL statement.

CREATETABLE MyTable (IDNumber (10)NotNULL, PaginatorNumber (10)NotNullValue VARCHAR2 (50))/AlterTABLE mytableadd constraint pk_mytable_id primary key (id)/create INDEX ix_mytable_paginator_id on mytable ( Paginator, id)/insertinto mytable (ID, Paginator, value) select level, level/10000 ,  ' Value ' | | levelfrom dualconnect by level <= 1000000/commit/ begin dbms_stats.gather_schema_stats (                

This SQL statement creates a table that contains 1 million data and creates a federated index.
Also, in this query, the Patinator field is unique in order to show the following phenomenon:
In a query, some data may appear multiple times in different paged queries, while some data may be based on not being queried
This is called paging chaos.

Then, we use Row_numer and rownum respectively to query, return 10 data information from 900001 to 900010.
Row_number ()

Select  *from    (        Select  t.*, Row_number () over (frommytable t)900010  
ID Paginator VALUE RN
900001 90 Value 900001 900001
900002 90 Value 900002 900002
900003 90 Value 900003 900003
900004 90 Value 900004 900004
900005 90 Value 900005 900005
900006 90 Value 900006 900006
900007 90 Value 900007 900007
900008 90 Value 900008 900008
900009 90 Value 900009 900009
900010 90 Value 900010 900010
Rows fetched in 0.0005s (0.8594s)
SELECT STATEMENT  VIEW   WINDOW nosort stopkey   20090506_rownum. ix_mytable_paginator_id 

RowNum

Select  *from    (        Select  as RN        by paginator, id) t)900010   
ID Paginator VALUE RN
900001 90 Value 900001 900001
900002 90 Value 900002 900002
900003 90 Value 900003 900003
900004 90 Value 900004 900004
900005 90 Value 900005 900005
900006 90 Value 900006 900006
900007 90 Value 900007 900007
900008 90 Value 900008 900008
900009 90 Value 900009 900009
900010 90 Value 900010 900010
Rows fetched in 0.0005s (0.7058)
SELECT STATEMENT  view   COUNT    view     20090506_rownum. ix_mytable_paginator_id   

As you can see from the above, the query using RowNum is slightly faster than the Row_number function.
Then looking at a row_number query, you can see that Oracle is smart enough to avoid sorting by using a federated index, and then you can quickly find the appropriate data information directly by using the Stopkey operation.
The rownum query also uses the index, but does not take advantage of the stopkey condition, just a simple count operation.
So, can you also let rownum use Stopkey? In the previous query, Oracle did not know that this RN is the alias of the inner query rownum, we can rewrite the query, use the rownum in the outer query, so that the stopkey condition can be exploited in the outer layer. This is the variant of our common Oracle3-layer pagination:

Select  *from    (        Select  as RN        by paginator, id) t)    
ID Paginator VALUE RN
900001 90 Value 900001 900001
900002 90 Value 900002 900002
900003 90 Value 900003 900003
900004 90 Value 900004 900004
900005 90 Value 900005 900005
900006 90 Value 900006 900006
900007 90 Value 900007 900007
900008 90 Value 900008 900008
900009 90 Value 900009 900009
900010 90 Value 900010 900010
Rows fetched in 0.0005s (0.4714s)
SELECT STATEMENT  count stopkey  VIEW    count     20090506_rownum. ix_mytable_paginator_id   

In this query, Oracle leverages the Stopkey, which is only 471ms faster than the original.

If Row_number and rownum use the same execution plan, why rownum is significantly faster.
This is because Oracle's history is too long, and different times cause the same features to have different effects.

RowNum was introduced in Oracle6, published in 1988, at the time of what resources and conditions are not met, as a simple counter, is considered very simple and efficient.
With the development of the times, more needs are mentioned, at this time, an equivalent but more powerful function than RowNum is introduced, this is the Row_number function, which is introduced from the oracle9i. At this time, efficiency is no longer the only condition, so the realization of row_number is no longer the only indicator of efficiency.

Of course, if you have more requirements, such as grouping and so on, you need to use the Row_number function, but if you are simply a paged query, it is recommended to use rownum, which is why rownum is still so popular in the present era ( It is said that there is the offset paging operator in oracle12c, and the Row_number function is used internally, so that RowNum can retire.

The following is the original English: http://explainextended.com/2009/05/06/oracle-row_number-vs-rownum/

Differences and linkages between Row_number and RowNum in Oracle (translation)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.