Attualità e Information Technology

July 29, 2007

Paging su SQL Server 2005

Filed under: IT, SQL

Problema tipico: abbiamo un bel po’ di record da mostrare nella nostra applicazione (win e soprattutto web) e vogliamo paginarli per una migliore lettura. Approccio tipico - io per primo per fretta e non curanza lo applico spesso e volentieri - è quello di tirare su con una query tutti i record e poi lasciare che sia il nostro gridview a preoccuparsi del paging.

Evidente problema di questo approccio: se i record sono tanti le performance diventano imbarazzanti. Ad ogni cambio di pagina infatti vengono inviati tutti i dati per poi visualizzarne una minima sottoparte.

Come detto, finchè sono pochi record si può lasciare anche così, ma se il numero sale (e non c’è neppure bisogno salga tanto invero) bisogna far qualcosa per migliorare le performance.

Soluzione: paginare sul database via sql.

Detto così pare banale, ma farlo su SQL Server non è mai stato molto semplice. Purtroppo in casa Microsoft non hanno ancora introdotto istruzioni tipo LIMIT di MySQL, ma in SQL Server 2005 hanno almeno introdotto il comando ROW_NUMBER() che ci semplifica la vita.

Vediamo come lo si può sfruttare in combinazione con le Common Table Expressions (CTE).

Supponiamo di avere la seguente query da voler eseguire:

SELECT idPersona, nome, cognome, dataNascita, codiceFiscale, sesso
FROM Persone
ORDER BY idPersona

Ora facciamone una CTE:

WITH PagedPersone AS
(
SELECT idPersona, nome, cognome, dataNascita, codiceFiscale, sesso
FROM Persone
)
SELECT idPersona, nome, cognome, dataNascita, codiceFiscale, sesso
FROM PagedPersone
ORDER BY idPersona

Ovviamente il risultato è analogo.

Ora è il momento di ROW_NUMBER(). Per dettagli sull’istruzione vi rimando al MSDN: ROW_NUMBER (Transact-SQL).

WITH PagedPersone AS
(
SELECT idPersona, nome, cognome, dataNascita, codiceFiscale, sesso, ROW_NUMBER() OVER (ORDER BY idPersona) AS RowNumber
FROM Persone
)
SELECT idPersona, nome, cognome, dataNascita, codiceFiscale, sesso
FROM PagedPersone
ORDER BY idPersona

Anche in questo caso il risultato della query è lo stesso, ma ora in PagedPersone abbiamo anche un numero (RowNumber) incrementale che “conta” le tuple. A questo punto fare il paging diventa banale.

DECLARE @PageNumber int
DECLARE @PageSize int
SET @PageNumber = 10;
SET @PageSize = 20;

WITH PagedPersone AS
(
SELECT idPersona, nome, cognome, dataNascita, codiceFiscale, sesso, ROW_NUMBER() OVER (ORDER BY idPersona) AS RowNumber
FROM Persone
)
SELECT idPersona, nome, cognome, dataNascita, codiceFiscale, sesso
FROM PagedPersone
WHERE RowNumber > ((@PageNumber - 1) * @PageSize) AND RowNumber <= (@PageNumber * @PageSize)
ORDER BY idPersona

Ecco dunque risolto il problema del paging. Testando la tecnica noterete quanto le performance migliorino.

Technorati tags , , , ,

AddThis Social Bookmark Button

2 Comments »

The URI to TrackBack this entry is: http://oplero.blogsome.com/2007/07/29/paging-su-sql-server-2005/trackback/

  1. mi sono imbattuto per caso in questo articolo, cercando su google come fare il paging a livello di DB…
    e oltre aver trovato un modo semplice, ho imparato anche le CTE (che non conoscevo).. che dire… grazie!!

    Comment by sstefano — January 13, 2008 @ 15:23

  2. Mi fa piacere che ti sia risultato utile ;)

    Comment by Alessio — January 13, 2008 @ 18:37

RSS feed for comments on this post.

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>


   

Get free blog up and running in minutes with Blogsome | Theme designs available here