Warsztat - Programowanie gier

Lipiec 30, 2010, 17:37:49 *
Witamy, Gość. Zaloguj się, lub zarejestruj proszę.

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności: Warsztat, Regulamin forum, #warsztat, Wiki, FAQ, NoPaste, Mapa
 
   Strona główna   Pomoc Szukaj Zaloguj się Rejestracja  
Strony: [1]
  Drukuj  
Autor Wątek: [postgresql] stronicowanie / paginacja  (Przeczytany 3800 razy)
Goliatus
Hero Member
*****

wiadomości: 975


Zobacz profil
« : Wrzesień 19, 2006, 15:55:17 »

Problem mam konkretny: jest sobie tabela z rekordami, z których każdy ma jakieś id.
Załóżmy, że chce mieć paginacje np. 20 rekordów na strone i teraz mając jakąś wartość id=X jak wyznaczyć numer strony, na której znalazłby się dany rekord nie używając zliczania i offset/limit większego niż 200.

Problem polega na tym, że postgre w zależności od ilości przydzielonej na niego pamięci, nie używa indeksów jeśli limit lub offset jest zbyt duże, a zliczanie to zliczanie. Przy dużej ilości rekordów zapytania wykonuja sie przez wiele sekund.

to co już wiem to dwie opcje:
  • [codei=sql]SELECT id FROM tabela WHERE id < wartosc /* dodatkowe warunki */ ORDER BY id ASC OFFSET 20 LIMIT 1[/codei]i powtarzanie tego w pętli, zliczając przebegi aż dojde do X. To jest szybsze niż użycie count(*).
  • osobna tabela, w której będę zapisywal informacje o stronach (numer_strony, pierwszy_rekord, ostatni_rekord), ale ze względu na dodatkowe warunki to jest kiepskie rozwiązanie
Zapisane
bies
Gość
« Odpowiedz #1 : Wrzesień 19, 2006, 16:21:14 »

Jak często usuwasz dane z tej tabeli?
Zapisane
Goliatus
Hero Member
*****

wiadomości: 975


Zobacz profil
« Odpowiedz #2 : Wrzesień 19, 2006, 16:23:13 »

Bardzo rzadko, praktycznie tylko dodaje.
Zapisane
bies
Gość
« Odpowiedz #3 : Wrzesień 19, 2006, 16:36:00 »

No to dodaj tam klucz zaciągający dane z sekwencji i normalnie wykonuj select * from tbl where idx >= 20*n and idx < 20*n + 20. A numer strony to  oczywiście idx / 20. Wink
« Ostatnia zmiana: Wrzesień 19, 2006, 16:37:58 wysłane przez bies » Zapisane
Goliatus
Hero Member
*****

wiadomości: 975


Zobacz profil
« Odpowiedz #4 : Wrzesień 19, 2006, 20:08:20 »

no to ok dla zapytania bez dodatkowych warunków
Zapisane
bies
Gość
« Odpowiedz #5 : Wrzesień 19, 2006, 20:24:23 »

No fakt, nie zauważyłem dodatkowych warunków. No to cóż, my preciousss PL/pqSQL. Otwórz kursor dla zapytania z warunkami. Przejdź (move) do początku strony. I pobierz (fetch) n danych.
Zapisane
Goliatus
Hero Member
*****

wiadomości: 975


Zobacz profil
« Odpowiedz #6 : Wrzesień 19, 2006, 21:35:33 »

A gdzie jest haczyk przy kursorach?  Grin
Zapisane
bies
Gość
« Odpowiedz #7 : Wrzesień 19, 2006, 22:16:17 »

A gdzie jest haczyk przy kursorach?  Grin
W postgresie to w ogóle nie wiem (poznaję go przy okazji odpowiadania na pytania na forum Grin ). Natomiast, widziałem różne operacje (o koszmarnym stopniu komplikacji) robione na Oracle'u w PL/SQL-u przez kolegów z pracy. Sam się zastanawiałem dlaczego to działa, na dodatek tak dobrze. Strzelam, że łatwiej jest skompilować i optymalizować operacje na danych w języku imperatywnym niż deklaratywnym. Ale do końca to sam nie wiem.

Tak czy inaczej, wypróbuj.
Zapisane
agent_J
Gość
« Odpowiedz #8 : Listopad 27, 2006, 09:12:58 »

A gdzie jest haczyk przy kursorach?  Grin
W postgresie to w ogóle nie wiem (poznaję go przy okazji odpowiadania na pytania na forum Grin ). Natomiast, widziałem różne operacje (o koszmarnym stopniu komplikacji) robione na Oracle'u w PL/SQL-u przez kolegów z pracy. Sam się zastanawiałem dlaczego to działa, na dodatek tak dobrze. Strzelam, że łatwiej jest skompilować i optymalizować operacje na danych w języku imperatywnym niż deklaratywnym. Ale do końca to sam nie wiem.

Tak czy inaczej, wypróbuj.


Może używają stored procedures, które są wiele szybsze niż przesyłanie zapytań do parsowania.
Zapisane
Goliatus
Hero Member
*****

wiadomości: 975


Zobacz profil
« Odpowiedz #9 : Listopad 30, 2006, 00:51:33 »

Przecież nie chodzi o szybkość parsowania zapytania tylko o to, czy silnik przy przeszukiwaniu tabeli wykorzystuje indeks czy nie, a to czy jest to wywoływane przez zapytanie czy poprzez procedure(np. w plpgqslu) to nie ma znaczenia. Dodatkowo procedury zrobione w plpgsqlu mają taką przypadłość, że jeśli dasz tam kilka updatów i/lub insertów dla kilku różnych tabel to silnik zakłada locka na wszystkie na wejściu do procki i zdejmuje dopiero po wyjściu. Nie wiem czemu, ale wygląda na to, że w taki dziwny sposób są one kompilowane.

A paginacje ostatecznie zrobiłem tak:
Cytuj
osobna tabela, w której będę zapisywal informacje o stronach (numer_strony, pierwszy_rekord, ostatni_rekord), ale ze względu na dodatkowe warunki to jest kiepskie rozwiązanie
Zapisane
Reg
Member2000
*******

wiadomości: 3791



Zobacz profil WWW
« Odpowiedz #10 : Listopad 30, 2006, 14:23:20 »

Ciekawy pomysł. W jaki sposób uaktualniasz tą tabelę? Obliczasz na której stronie znajdzie się dodawany czy usuwany rekord i uaktualniasz informacje o wszystkich następnych stronach w tej tabeli?
Zapisane

Strony: [1]
  Drukuj  
 
Skocz do:  

Hosting: Polska Strefa - Ogłoszenia
Powered by SMF 1.1.7 | SMF © 2006, Simple Machines LLC