Comparison of several common SQL paging Methods

Source: Internet
Author: User

Paging is very important and will be encountered during the interview. Let's review and summarize it.

1. Create a test environment (it takes about 5 minutes to insert 1 million data records ).

 Create Database dbtest 
Use dbtest

-- Create a test table
Create Table pagetest
(
Id int identity (1, 1) not null,
Col01 int null,
Col02 nvarchar (50) null,
Col03 datetime null
)

-- 10 thousand record set
Declare @ I int
Set @ I = 0
While (@ I <10000)
Begin
Insert into pagetest select cast (floor (RAND () * 10000) as INT), left (newid (), 10), getdate ()
Set @ I = @ I + 1
End

2. Several Typical paging SQL statements. The following example shows 50 lines per page, 198*50 = 9900, and the data on 199th pages is obtained.

 -- Statement 1, not in/top
Select top 50 * From pagetest
Where id not in (select top 9900 ID from pagetest order by ID)
Order by ID




-- Statement 2, not exists
Select top 50 * From pagetest
Where not exists
(Select 1 from (select top 9900 ID from pagetest order by ID) A where a. ID = pagetest. ID)
Order by ID

-- Statement 3, max/top
Select top 50 * From pagetest
Where ID> (select max (ID) from (select top 9900 ID from pagetest order by ID))
Order by ID

-- Statement 4, row_number ()
Select top 50 * from
(Select row_number () over (order by ID) rownumber, * From pagetest)
Where rownumber> 9900

Select * from
(Select row_number () over (order by ID) rownumber, * From pagetest)
Where rownumber> 9900 and rownumber <9951

Select * from
(Select row_number () over (order by ID) rownumber, * From pagetest)
Where rownumber between 9901 and 9950

-- Write 5: The row_number () variant shown in the post on csdn does not generate record numbers based on existing fields. Filter and sort records by conditions first, then a constant column in The result set is used to generate the record serial number.
Select *
From (
Select row_number () over (order by tempcolumn) rownumber ,*
From (select top 9950 tempcolumn = 0, * From pagetest where 1 = 1 order by ID)
) B
Where rownumber> 9900

3. perform tests in the 10 thousand, 0.1 million (take 1990 pages), and 100 (take 19900 pages) records sets.

Test SQL:

Declare @ begin_date datetime
Declare @ end_date datetime
Select @ begin_date = getdate ()

<...... Your code ......>

Select @ end_date = getdate ()
Select datediff (MS, @ begin_date, @ end_date) as 'millisecond'

 

10 thousand: Basically there is no difference.

0.1 million:

1 million:

 

4. Conclusion:

1. Max/top and row_number () are all good paging methods. Compared with row_number (), it only supports sql2005 and later versions. Max/top has better portability and can be applied to both SQL2000 and access.

2. Not exists feels a little more efficient than not in.

3. The efficiency of writing three row_number () statements is similar.

4. The variation of row_number () is based on my test efficiency. Original post http://topic.csdn.net/u/20100617/04/80d1bd99-2e1c-4083-ad87-72bf706cb536.html here

 

PS. The above paging sorting is based on the ID of the auto-increment field. The test environment also provides int, nvarchar, and datetime fields. You can also try them. However, the sorting efficiency of large data volumes without indexes for non-primary keys should be unsatisfactory.

 

5. encapsulate rownumber and max/top into the stored procedure.

Rownumber ():

 Create proc [DBO]. [spsqlpagebyrownumber] 
@ Tbname varchar (255), -- table name
@ Tbfields varchar (1000), -- Return Field
@ Pagesize int, -- page size
@ Pageindex int, -- page number
@ Strwhere varchar (1000), -- Query Condition
@ Strorder varchar (255), -- sorting Condition
@ Total int output -- total number of returned records
As
Declare @ strsql varchar (5000) -- subject sentence
Declare @ strsqlcount nvarchar (500) -- query the total number of records.

-------------- Total number of records ---------------
If @ strwhere! =''
Begin
Set @ strsqlcount = 'select @ totalcout = count (*) from '+ @ tbname + 'where' + @ strwhere
End
Else
Begin
Set @ strsqlcount = 'select @ totalcout = count (*) from' + @ tbname
End
-------------- Pagination ------------
If @ pageindex <= 0
Begin
Set @ pageindex = 1
End

Set @ strsql = 'select * from (select row_number () over ('+ @ strorder +') rowid, '+ @ tbfields
+ 'From' + @ tbname + 'where 1 = 1' + @ strwhere + ') TB where TB. rowid>' + STR (@ PageIndex-1) * @ pagesize)
+ 'And TB. rowid <=' + STR (@ pageindex * @ pagesize)

Exec sp_executesql @ strsqlcount, n' @ totalcout int output', @ total output
Exec (@ strsql)

Max/top: (if you write it down, the name of the primary key field must be "ID ")

 Create proc [DBO]. [spsqlpagebymaxtop] 
@ Tbname varchar (255), -- table name
@ Tbfields varchar (1000), -- Return Field
@ Pagesize int, -- page size
@ Pageindex int, -- page number
@ Strwhere varchar (1000), -- Query Condition
@ Strorder varchar (255), -- sorting Condition
@ Total int output -- total number of returned records
As
Declare @ strsql varchar (5000) -- subject sentence
Declare @ strsqlcount nvarchar (500) -- query the total number of records.

-------------- Total number of records ---------------
If @ strwhere! =''
Begin
Set @ strsqlcount = 'select @ totalcout = count (*) from '+ @ tbname + 'where' + @ strwhere
End
Else
Begin
Set @ strsqlcount = 'select @ totalcout = count (*) from' + @ tbname
End
-------------- Pagination ------------
If @ pageindex <= 0
Begin
Set @ pageindex = 1
End

Set @ strsql = 'select top '+ STR (@ pagesize) +' * from' + @ tbname +'
Where ID> (select max (ID) from (select top '+ STR (@ PageIndex-1) * @ pagesize) + 'id from' + @ tbname + ''+ @ strorder + '))
'+ @ Strorder +''

Exec sp_executesql @ strsqlcount, n' @ totalcout int output', @ total output
Exec (@ strsql)

Found in the garden max/top such a version, looks very powerful, http://www.cnblogs.com/hertcloud/archive/2005/12/21/301327.html

Call:

 
Declare @ count int
-- Exec [DBO]. [spsqlpagebyrownumber] 'pagetest ',' * ', 50, 20,', 'order by id asc ', @ count output
Exec [DBO]. [spsqlpagebymaxtop] 'pagetest ',' * ', 50, 20,', 'order by id asc ', @ count output
Select @ count

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.