SQL Paging

Van egy alapszabály a lekrédezéseknél, amit nagyon sokan – leginkább az üzleti felhasználók – elfelejtenek, mégpedig az, hogy csakis annyi adatot jelenítsünk meg, amennyire tényleg szükség van és kezelhető mennyiség. Ez valamikor 1 sor, de előfordulhat, hogy több száz sorról van szó. Ez utóbbit egy weboldalon megjeleníteni nem egy jó ötlet, lassú lehet az oldal betöltése; itt jön képbe a paging, lapozás.

Képzeljük el, hogy van egy weboldal, amin egy GridView-ban szeretnénk megjeleníteni sok-sok sort és oszlopot. A cél az, hogy a sorok száma egy oldalon a web fejlesztő által állítható legyen és meg tudja adni az oldal számát is. Az alábbi kód egy minta a lapozás megvalósításához:

USE [tempdb];
GO

--teszt tábla létrehozása, aminek az adatait fogjuk "lapozni"
CREATE TABLE [dbo].[PagingTestTable]
(
	[id] int identity,
	[name] varchar(10)
);
GO

--feltöltjük adattal a teszt táblát
DECLARE @i int;
SET @i = 0;

WHILE @i < 1000
	BEGIN
		INSERT INTO [dbo].[PagingTestTable] ([name]) VALUES ('row' + CAST(@i AS varchar(4)));
		--SQL 2008+
		SET @i += 1;
		--SQL 2005
		--SET @i = @i + 1;
	END;
GO

--példa: 10 sor egy oldalon és a 2. oldalt akarjuk látni
DECLARE @Page int;
DECLARE @PageSize int;

SET @Page = 2;
SET @PageSize = 10;


;WITH CTE AS
(
	SELECT
		ROW_NUMBER() OVER (ORDER BY [ID] ASC) AS [Row],
		[name]
	FROM
		[dbo].[PagingTestTable]
)
SELECT * FROM CTE
WHERE
	[Row] BETWEEN (@Page * @PageSize) - @PageSize + 1 AND (@Page * @PageSize);

A kód SQL 2005 és újabb verziókon működik. A Denali-ban – ami már az SQL Server 2012 nevet viseli – az OFFSET parancs is használható.

Comments (2) -

Erdekes poszt, habar en eddig mindig kikerultem a lapozast sql oldalon. Az oka pedig, hogy minden egyes lapozasnal a teljes query-nek le kell futnia ahhoz hogy meghatarozzuk a kivalasztott oldal tartalmat. Ez eleg nagy overhead az sql-nek kulonosen ha rendezni, es szurni kell generalt oszlopon. Emiatt altalaban vagy sqldatasource-ot hasznalok cache-el, vagy ha az nem megfelelo akkor server oldali cache. Ez jellemzoen kevesebb mint 5k RAM a szerveren,viszont gyorsabb oldalbetoltes mivel nem kell az sql serverhez csatlakozni plusz az sql szerveren is kisebb a terheles. Persze ha az adat percenkent valtozik ez a megoldas nem szerencses, es marad a lapozas...

Nem feltétlenül overhead az sql oldalon, bár abban teljesen egyetértek, hogy a cache a legjobb megoldás lehetne, sőt a Query Notificaton ha figyelni kell a változást is. Van sajnos olyan eset, amikor csak így lehet megoldani egy lapozást, pl VLDB-k vagy "nagy" táblák esetében ez jobb lehet.

Add comment