Vous êtes sur la page 1sur 3

A common activity in applications is to page results or record sets from a database.

This is usually done on the client using the client's paging functionality or on the server through a variety of methods. In SQL Server 2000 those server side methods typically used dynamic SQL or nested T ! clauses and "eren't very efficient. #sing $ommon Table %&pressions in SQL Server 200' "e have a better "ay to page record sets on the server. The (embers !age on SQLTeam.com lists the first 20 members sorted by number of posts. In order to generate this it selects the entire set of members) returns it to the client and then displays the first 20 ro"s using A* 's paging functionality. The S%L%$T statement it runs loo+s something li+e this, SELECT M_NAME, M_POSTS, M_LASTPOSTDATE, M_LASTHEREDATE, M_DATE, M_COUNTRY FROM dbo.FORUM_MEMBERS ORDER BY M_POSTS DESC; It has a cost of -.2 and does appro&imately .)/// logical page reads to return the 2')000 registered members in our forum. It does have the benefit of being very simple to "rite. $onverting this 0uery to a $ommon Table %&pression 1$T%2 is straightfor"ard and that loo+s li+e this, WITH PagedMembe ! AS " SELECT M_NAME, M_POSTS, M_LASTPOSTDATE, M_LASTHEREDATE, M_DATE, M_COUNTRY FROM dbo.FORUM_MEMBERS # SELECT M_NAME, M_POSTS, M_LASTPOSTDATE, M_LASTHEREDATE, M_DATE, M_COUNTRY FROM PagedMembe ! ORDER BY M_POSTS DESC; This 0uery has the e&act same e&ecution plan) 0uery cost and logical reads "hen you run it. At this point all the $T% has give us is a named "rapper around a simple 0uery. The 3IT4 clause defines the name of the $T% as 5!aged(embers5 In fact) it acts an a"ful lot li+e a derived table. SQL Server 200' adds a number of functions that are useful "ith common table e&pressions. ne of these is 6 378#(9%6. If "e include this in our $T% our ne" 0uery loo+s li+e this, WITH Membe ! AS " SELECT M_NAME, M_POSTS, M_LASTPOSTDATE, M_LASTHEREDATE, M_DATE, M_COUNTRY, ROW_NUMBER"# O$ER "ORDER BY M_POSTS DESC# AS Ro%N&mbe

FROM dbo.FORUM_MEMBERS # SELECT Ro%N&mbe , M_NAME, M_POSTS, M_LASTPOSTDATE, M_LASTHEREDATE, M_DATE, M_COUNTRY FROM Membe ! WHERE Ro%N&mbe BETWEEN ' AND () ORDER BY Ro%N&mbe ASC; The 6 378#(9%6 function needs an :%6 clause. In our e&ample the :%6 clause contains an 6*%6 9; clause. This <ust tells the 6 378#(9%6 function in "hat order to generate the ro" numbers. It's possible to have multiple 6 378#(9%6 functions in a single S%L%$T statement each "ith their o"n ordering. ;ou can see "e aliased the 6 378#(9%6 function and then referenced that column in the 34%6% clause of the outer S%L%$T statement. This only selects the first t"enty members from those "ith the most posts. This 0uery has a cost of 0.- and does =. logical reads. It runs faster because it's able to use an inde& on (7! STS that the other 0ueries "eren't able to ta+e advantage of. If that inde& "eren't there it "ould have the performance as the other 0uery but return much less data to the client. As you increase the number of ro"s returned or ho" far do"n into the results you go the logical reads "ill increase. n my 0uery the brea+even "as around '00 ro"s. If I'm loo+ing for a page that starts at ro" '00 or earlier this method is faster >> or at least has fe"er logical reads. If I'm loo+ing for a page that starts after ro" '00 then the table scan "as faster. I'm most cases people aren't paging past the first fe" pages of results. ;ou can also use the 6 378#(9%6 function in a straight S%L%$T statement li+e this, SELECT M_NAME, M_POSTS, M_LASTPOSTDATE, M_LASTHEREDATE, M_DATE, M_COUNTRY, ROW_NUMBER"# O$ER "ORDER BY M_POSTS DESC# AS Ro%N&mbe FROM dbo.FORUM_MEMBERS ORDER BY M_POSTS DESC; This "ill return a column for the ro" number but you "on't be able to use it in the 34%6% clause. ;ou'll have to "rite it in a $T% or a derived table for that to "or+. $ommon table e&pressions also e&pect to be the first statement in a batch or they e&pect the statement preceding them to be terminated "ith a semicolon. ;ou can easily use variables to determine "hich ro"s to S%L%$T by passing in parameters for the page si?e and "hich page to return, DECLARE *PageS+,e INT, *PageN&mbe INT, *F+ !-Ro% INT, *La!-Ro% INT SELECT *PageS+,e . (), *PageN&mbe . /

SELECT *F+ !-Ro% . " *PageN&mbe 0 '# 1 *PageS+,e 2 ', *La!-Ro% . "*PageN&mbe 0 '# 1 *PageS+,e 2 *PageS+,e ; WITH Membe ! AS " SELECT M_NAME, M_POSTS, M_LASTPOSTDATE, M_LASTHEREDATE, M_DATE, M_COUNTRY, ROW_NUMBER"# O$ER "ORDER BY M_POSTS DESC# AS Ro%N&mbe , ROW_NUMBER"# O$ER "ORDER BY M_NAME DESC# AS Ro%N&mbe ( FROM dbo.FORUM_MEMBERS # SELECT Ro%N&mbe , M_NAME, M_POSTS, M_LASTPOSTDATE, M_LASTHEREDATE, M_DATE, M_COUNTRY FROM Membe ! WHERE Ro%N&mbe BETWEEN *F+ !-Ro% AND *La!-Ro% ORDER BY Ro%N&mbe ASC; $ommon table e&pressions and the 6 378#(9%6 function are a handy "ay to server side paging on a 0uery result.

Vous aimerez peut-être aussi