Gestire la paginazione dei dati con SQL Server

di Riccardo Golia

Ho trovato interessante l'articolo di Lorenzo Braidi sulla gestione della paginazione dei dati presente nel numero di novembre 2004 di Computer Programming. In particolare si spiega come riuscire ad estrarre da una tabella contenente una grande mole di dati un numero di record esattamente pari ad una prefissata dimensione di pagina.

Nel caso di SQL Server il trucco sta nell'annidare tre query una dentro all'altra:

  • la prima query estrae tutti i record fino al limite superiore filtrandoli e ordinandoli secondo quanto richiesto dall'applicazione;
  • la seconda query prende il resultset della prima, ordinato in maniera decrescente, limitatamente ai record da inserire nella pagina;
  • la terza query ripristina l'ordinamento della prima query sui record della pagina.

La query complessiva dovrebbe pertanto avere una forma di questo tipo:

SELECT TOP [dimPage] [field1], [field2], ... 
FROM (SELECT TOP [dimPage] [field1], [field2], ... 
FROM (SELECT TOP ([dimPage] * [numPage]) [field1], [field2], ... 
FROM [table] 
WHERE [conditions] 
ORDER BY [order] ASC) AS TMP1 
ORDER BY [order] DESC) AS TMP2 
ORDER BY [order] ASC

Commenti
shardick scrive:
Gestire la paginazione dei dati con SQL Server

mi sorprendevo come in tutti gli articoli che ho letto non si è mai occupato di sapere quante righe effettivamente tornasse la query senza filtro :D

questo è un modo per avere il numero totale di righe senza riscrivere effettivamente la query due volte:

SELECT *,
ROW_NUMBER() OVER (ORDER BY field) as num
into #tmp
FROM tbl

SELECT @count = count(0) FROM #tmp

SELECT * from #tmp
WHERE num BETWEEN @min AND @max
11/04/2008 ore 10.29
TrackBack scrive:
30/06/2005 ore 11.41
TrackBack scrive:
09/12/2004 ore 13.50
lorenzobraidi scrive:
Gestire la paginazione dei dati con SQL Server -

Innanzitutto, sono lusingato per l'attenzione che avete prestato all'articolo pubblicato su CP 140 :-)


Cerco di rispondere ad alcuni dei commenti che ho letto...
Per ottenere il numero totale dei record che verrebbero estratti dalla query, non c'è altra strada se non quella di eseguire una select count preventivamente.
Tra l'altro - se leggete l'intero articolo è scritto anche li - la selezione preventiva per ottenere il numero totale dei record è da fare anche per un altro motivo.
Se non sappiamo quanti siano i record, infatti, non ci accorgeremmo mai di essere arrivati alla fine del nostro resultset! Per come è strutturata la query, infatti, all'aumentare del numero della pagina che si vuole estrarre, si otterrebbe sempre l'ultima.
Se per esempio la nostra tabella avesse 100 record e noi li estraessimo in pagine da 20 ciascuna, le prime 5 pagine sarebbero corrette. Nel momento in cui estraessimo la sesta, però, otterremmo nuovamente i dati presenti nella quinta...

Un altro commento, poi, proponeva una soluzione alternativa che condivido.
La soluzione, in pratica, prevede di estrarre i record appartenenti alle pagine che si vogliono saltare per poi eseguire una query NOT IN che va a prendere i primi record successivi a quelli identificati in precedenza.
La soluzione, però, è efficace solo se si utilizza come criterio di ordinamento la chiave primaria della tabella o uno o più campi che ne costituiscano un indice univoco.

Grazie comunque per l'attenzione e l'interesse
Lorenzo Braidi
lorenzo__@__braidi.com (eliminare i __)
http:\\www.braidi.com
09/12/2004 ore 9.26 | 1 risposta
»»»» rickyvr scrive:
Re: Gestire la paginazione dei dati con SQL Server -

Lorenzo, grazie a te per le puntualizzazioni...

Chi meglio dell'autore può spiegare e approfondire al meglio i concetti esposti nell'articolo?!?!

Ciao, Ricky.
09/12/2004 ore 10.11
andrewz scrive:
Gestire la paginazione dei dati con SQL Server -

E se volessi sapere contemporaneamente quanti record totali sono restituiti dalla query?

Ciao!
07/12/2004 ore 13.05 | 7 risposte
Daniele Bochicchio scrive:
Re: Gestire la paginazione dei dati con SQL Server -

usi una SP con output parameter come faccio io nel 99% dei casi, usando una tab temporanea
imho il codice della SP è sicuramente più leggibile e diventa difficile fare errori, oltre che più semplice manutenerla.
07/12/2004 ore 13.07
»»»» rickyvr scrive:
Re: Gestire la paginazione dei dati con SQL Server -

La query restituisce al massimo [dimPage] records.
Cosa intendi per record totali?

Ciao, Ricky.
07/12/2004 ore 13.08 | 1 risposta
Daniele Bochicchio scrive:
Re: Gestire la paginazione dei dati con SQL Server -

quelli che la query darebbe come totale.
se fai la paginazione, devi pur sapere fino a quale pagina arriva...
07/12/2004 ore 15.42 | 1 risposta
andrewz scrive:
Re: Gestire la paginazione dei dati con SQL Server -

Ora mi avete fatto venire un dubbio: è meglio l'utilizzo della tabella temporanea oppure l'esecuzione di due query, una per il conteggio e la seguente con l'uso del TOP per avere solo i record necessari? (Io ho sempre preferito la tabella temporanea).

Forse che l'uso della tabella temporanea pregiudica le prestazioni con query che restituiscono centinaia di migliaia (se non milioni) di record?

Ciao
14/12/2004 ore 20.51 | 2 risposte
»»»» rickyvr scrive:
Re: Gestire la paginazione dei dati con SQL Server -

Sull'articolo di Lorenzo Braidi su CP sono riportati i grafici con le prestazioni relative ad una simulazione con 1000 pagine da 20 righe ciascuna. Si parla di un tempo medio di risposta compreso tra i 300 e i 400 ms. Per le prime 20/30 pagine si parla addirittura di tempi inferiori al decimo di secondo. Si può inoltre rilevare un progressivo deterioramento delle prestazioni di tipo esponenziale a partire dalla novantesima pagina circa. Questi tempi sono addirittura migliorabili introducendo un indice sulla colonna di ordinamento dei dati. Si parla di tempi inferiori al decimo o poco più (sotto i 50 ms per le prime 350/400 estrazioni) usando l'indice.

Ciao, Ricky.
14/12/2004 ore 21.14
Daniele Bochicchio scrive:
Re: Gestire la paginazione dei dati con SQL Server -

guarda, la paginazione su questo sito è fatta con una tab temporanea, che è popolata (a seconda della ricerca) da altre 3-4 SP che eseguono query full text.
la tabella temporanea ha ovviamente un paio di colonne indicizzate e viene ordinata in base al rank, quindi vengono estratti i dati contenuti all'interno.
ci sono un po' di ottimizzazioni qua e la', ma direi che come puoi vedere tu stesso facendo una ricerca anche banale (tipo ASP) le prestazioni sono ottime. per il resto, ricky ha aggiunto un po' di dettagli
15/12/2004 ore 9.45 | 1 risposta
andrewz scrive:
20/12/2004 ore 20.09
ITHost scrive:
Gestire la paginazione dei dati con SQL Server -

prova a dare un occhio alla simulazione della clausula LIMIT in sql server e avrai lo stesso risultato

http://blogs.aspitalia.com/cp/post520.aspx
07/12/2004 ore 12.42

Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.

Nella stessa categoria
I più letti del mese
TagCloud
BLOG INFO
  • 166 post, 106 commenti, 63 trackback
  • Feed blog e contenuti tecnici: RSS
  • Feed blog: RSS Atom
IN EVIDENZA