SQL - stronicowanie danych

0

Sytuacja przedstawia sie nastepujaco:
Mam tabele z duza iloscia rekordow (x milionów).

Chce wybierac te dane stronicujac je aby uniknac przetwarzania niepotrzebnych wierszy, a co za tym idzie nie zarzynac serwera.
Dane wyswietlane sa na 'stronach' po 50 rekordow.

Dodatkowo dane sortowane sa po unikalnym identyfikatorze (int) lub nazwie (string) - ale jakby globalnie dla calej tabeli przed wybraniem, a nie tylko juz wybrane rekordy (wiec setna strona bedzie zawierac inne dane przy sortowaniu po identyfikatorze, a inne jesli posortujemy po nazwie rekordu).

O ile z sortowaniem po unikalnym identyfikatorze sie uporalem to z sortowaniem po nazwie, ktora moze sie powtarzac w obrebie wielu identyfikatorow mam juz problem :)

Przyklad uproszczony do samej istoty problemu (dane sortujmy wylacznie rosnaco):

Tabela -

CREATE TABLE [dbo].[TestTbl](
	[ID] [int] NULL,
	[Name] [varchar](10) NULL
) ON [PRIMARY]

Dadane z tabeli wybiera procedura, ktora jako parametry przyjmuje ilosc rekordow na stronie oraz numer strony.
Oto ona:

CREATE PROCEDURE Paging
	@aPageSize int,
	@aPage int,
	@aOrder int
AS
BEGIN
	DECLARE @lFirstRow int
	SET @lFirstRow=1+@aPage*@aPageSize

	DECLARE @lFirstID int
	
	SET ROWCOUNT @lFirstRow
	
	IF @aOrder=0 -- sortowanie po ID
	BEGIN
		SELECT	@lFirstID=[TestTbl].[ID]
		FROM	[TestTbl]
		ORDER BY [TestTbl].[ID] ASC

		SET ROWCOUNT @aPageSize
		SELECT	[ID], [Name]
		FROM	[TestTbl]
		WHERE	[TestTbl].[ID]>=@lFirstID
		ORDER BY [TestTbl].[ID] ASC
		RETURN 0;
	END

	IF @aOrder=1 -- sortowanie po Nazwie
	BEGIN
-- ???
	END
END

Algorytm stronicowania po ID dziala tak:

  1. licze numer pierwszego rekordu na podstawie rozmiaru oraz numeru strony
    (dla strony 3 bedzie to rekord 150 przy zalozeniu ze strona zawiera 50 pozycji)
  2. wybieram ID pierwszego rekordu na stronie
  3. ustawiam wybranie pierwszych 50 wierszy wyniku zapytania [SET ROWCOUNT @aPageSize]
    (dziala tak jak klauzula TOP)
  4. wybieram rekordy, ktore sa wieksze badz rowne ID wybranemu w kroku 2 (>= bo sortowanie rosnace)
    i wsio.

Jak widac nie ma tutaj specjalnej filozofii, ale problem pojawia się jesli chce posortowac po nazwie gdyz nazwy moga sie powtarzac.
Bedzie to skutkowalo bledna lista wynikow w momencie kiedy na poprzedniej stronie znajda sie te same nazwy co na wybieranej - w skrajnym przypadku wszystkie nazwy identyczne.

Trzeba wiec na pewno posortowac najpierw po nazwie, potem po identyfikatorze (ORDER BY [Name], [ID])...
ale tutaj juz nie mam pomyslow jak to zrealizowac.

Czy przychodzi komus jakis pomysl do glowy?
Z gory dziekuje i pozdrawiam :)

0

Mała poprawka:

  1. licze numer pierwszego rekordu na podstawie rozmiaru oraz numeru strony
    (dla strony 3 bedzie to rekord 150 przy zalozeniu ze strona zawiera 50 pozycji)

Oczywiście miałem na myśli 101 rekord ;) (stronicowanie od 0)

0

Jaki SZBD i technologia dostepu do bazy? Wiele sterownikow pozwala na otwieranie przewijalnych recordsetow, ktore nie pobieraja wszystkiego na raz.

0

MS SQL, ADO.NET

0
SELECT TOP 50 * FROM TestTbl WHERE ID NOT IN (SELECT TOP 100 * ID FROM TestTbl ORDER BY Name) ORDER BY Name

daje Ci od 101 do 150 i tak samo dla id (zmieniasz kolumnę w order by) tylko nie wiem jak to będzie działało dla dalszych stron

0

Super, dziki Misiekd.
Rozwiazanie dziala, sam bym na to nie wpadl, ale zastanawiam sie jak bedzie z wydajnoscia.
Musze to sprawdzic.
Ktos moze juz to przerabial?

1 użytkowników online, w tym zalogowanych: 0, gości: 1