Hay otras bases del mercado que ya hace bastante tiempo tienen este concepto, pero en SQL Server si queriamos no traer toda la consulta sino solamente una parte la única herramienta con la que contabamos era la sentencia TOP (o algunas trampas para poder simular la paginacion). La sentencia TOP nos permitía traer solamente los N primeros valores de una consulta. Pero es muy habitual tener una interfaz de cara al cliente que le muestra un gran resultado por páginas, entonces desearía poder traer solamente lo que voy a mostrar, y para la primer página me sirve el TOP pero para el resto no.
Con el objetivo de apalear este problema es que se incorporó OFFSET y FETCH. Al utilizar estas sentencias en lugar de devolver todos los valores, devuelve a partir del valor indicado en OFFSET. ¿Cuantos valores retirna? la cantidad que se indique en FETCH.
Para que esto funcione es necesario que la consulta tenga un ORDER BY. Veamos un ejemplo.
-- ============================================= -- Create: Andrés Aiello -- Create date: 13/01/12 -- Description: Paginacion en SQL 2012 -- ============================================= -- Llenemos una tabla con valores para poder probar CREATE TABLE #Temp(id INT PRIMARY KEY, campo2 INT, campo3 VARCHAR(100)) DECLARE @i INT SET @i = 0 WHILE @i<100 BEGIN INSERT INTO #Temp SELECT @i, @i*7, 'Fila ' + CAST(@i AS VARCHAR) SET @i = @i + 1 END GO -- Primera prueba: ver el contenido SELECT * FROM #Temp GO -- Forma vieja de paginar SELECT TOP 10 * FROM #Temp ORDER BY campo2 SELECT TOP 10 * FROM #Temp WHERE campo2>=70 ORDER BY campo2 -- Forma nueva de paginar -- Obtengo los primeros 10 resultados SELECT * FROM #Temp ORDER BY campo2 OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY; -- Obtengo los siguientes 10!!! SELECT * FROM #Temp ORDER BY campo2 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY; GO DROP TABLE #Temp GO
Según la documentación oficial se recomienda utilizar FETCH en lugar del viejo TOP. El motivo es que con el TOP es necesario ejecutar tantas consultas como páginas si deseen, y siempre es necesario hacer nuevamente una búsqueda. Con el FETCH el motor se encarga de que cuando volvamos a pedir algo no requiera reprocesarlo sino utilizar lo que ya se calculó.
Para que esto funcione correctamente se deben cumplir algunas simples condiciones:
- La informacion a consultar no debe cambiar entre consulta y consulta
- El ORDER BY debería ser sobre una columna (o varias) que sea única
Si todo esto se cumple (lo cual no es complicado) podremos comenzar a disfrutar de los beneficios del FETCH.
El FETCH no guarda los datos y en cada página ejecuta nuevamente la query.
ResponderEliminarEn http://goo.gl/3nmxT dice "Using OFFSET and FETCH as a paging solution requires running the query one time for each "page" of data returned to the client application". Se puede verificar en el plan.
Los dos requerimientos que mencionas son para garantizar consistencia entre las páginas.
Ing. Jose Mariano Alvarez
http://blog.josemarianoalvarez.com