Seite 1 von 2

PostgreSQL LIMIT / OFFSET [erledigt]

Verfasst: So, 15. Jul 2012 6:12
von AUGE_OHR
hi,

wenn ich "SELECT ... LIMIT 100" verwende

Frage : passiert das ab der "aktuellen" Position ?

klar wenn ich die Table noch nicht geöffnet habe wird er die ersten 100 "ORDER __record" nehmen.
wenn ich nun auf Position 50 "stehe" und wieder "SELECT ... LIMIT 100" abschicke ... 50-150 ?

oder muss ich so was machen

Code: Alles auswählen

"SELECT ... WHERE __record > 50 LIMIT 100"
Frage : : was passiert wenn mit mit LIMIT das "Ende" (EOF) überschreite ?

LIMIT ist ja "vorwärts", ist "OFFSET" dann "rückwärts" ?

wenn ich nun auf Position 150 stehe und

Code: Alles auswählen

"SELECT ... WHERE __record < 150 OFFSET 100"
eingebe wäre das dann von 150-50 ?

Frage : : was passiert wenn mit mit OFFSET den "Anfang" (BOF) überschreite ?

Re: PostgreSQL LIMIT / OFFSET

Verfasst: So, 15. Jul 2012 6:54
von georg
Hallo, Jimmy -


lies hier:

http://www.postgresql.org/docs/8.1/stat ... limit.html

Ein Limit beginnt mit dem ersten Satz, der durch das entsprechende Statement (gilt sowohl für SELECT, UPDATE, DELETE) ausgewählt wird, und die nachfolgenden, ebenfalls den Kriterien entsprechenden Sätze.

SELECT * FROM table WHERE bedingung LIMIT 50

liefert also die ersten 50 Sätze im Result Set (sofern 50 oder mehr gefunden werden, ansonsten nur die tatsächlichen Treffer, wenn die Anzahl < 50 ist).

SELECT * FROM table WHERE bedingung LIMIT 50 OFFSET 100

liefert 50 Sätze, und zwar aus einem vollständigen Result Set die Sätze 101 bis 150 (sofern mindestens 150 Sätze gefunden wurden).


Gruss,

Georg

P.S.: Du solltest eine Email von mir bekommen haben.

Re: PostgreSQL LIMIT / OFFSET

Verfasst: So, 15. Jul 2012 7:33
von AUGE_OHR
moin,
ich hatte OFFSET im PG Handbuch Seite 106 von 960 gefunden ... aber als Newbie nicht "verstanden"
georg hat geschrieben: Ein Limit beginnt mit dem ersten Satz, der durch das entsprechende Statement (gilt sowohl für SELECT, UPDATE, DELETE) ausgewählt wird, und die nachfolgenden, ebenfalls den Kriterien entsprechenden Sätze.

SELECT * FROM table WHERE bedingung LIMIT 50

liefert also die ersten 50 Sätze im Result Set (sofern 50 oder mehr gefunden werden, ansonsten nur die tatsächlichen Treffer, wenn die Anzahl < 50 ist).

SELECT * FROM table WHERE bedingung LIMIT 50 OFFSET 100

liefert 50 Sätze, und zwar aus einem vollständigen Result Set die Sätze 101 bis 150 (sofern mindestens 150 Sätze gefunden wurden).
DANKE =D> jetzt hab ich es wohl verstanden.

als wenn ich eine Datei mit FRead einlesen würde kann ich mit OFFSET die "Start Position" festlegen und LIMIT wäre analog dazu FRead(,,LEN(cBuffer))
georg hat geschrieben:P.S.: Du solltest eine Email von mir bekommen haben.
noch nicht ...

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 18. Jul 2012 6:22
von AUGE_OHR
hi,

bei SQL geht es normal um grösse Datenmengen. Zum Anzeigen reicht mir aber ein LIMIT aus.

Frage : ist "LIMIT 1 OFFSET yyy" für SQL "sinnvoll" als "Übersetzung" von SKIP ?

... ich frage mich ob ich das in einem "SQLskipper" verwenden könnte :?:

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 18. Jul 2012 8:20
von georg
Hallo, Jimmy -


aus meiner Sichtweise ist es NICHT sinnvoll, wenn du die Skipper-Methode auf diese Art und Weise abbilden willst. Bei jedem Aufruf muss der Server die Daten erneut "zusammensuchen", während bei einem Bewegen durch das Result Set (siehe Hector's result set Implmentierung) der Server eine entsprechend grosse Datenmenge direkt zur Verfügung stellt. Der Zeitaufwand server-seitig dürfte dadurch deutlich geringer sein.


Gruss,

Georg

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Do, 19. Jul 2012 6:56
von AUGE_OHR
georg hat geschrieben:aus meiner Sichtweise ist es NICHT sinnvoll,
klar ... aber es "würde" gehen" ?

noch ein was mir auffällt ( und ich nicht verstehe )

Code: Alles auswählen

ELSEIF nKey = xbeK_CTRL_PGDN
   ::hide()
   IF ::_nTablelen > 0
      nOff := ::_nTablelen - ::_nMaxRow
      ::_cOffset := LTRIM( STR( nOff ) )
      ::ReadNextData(,,,,, ::_cOffset )
   ELSE
      TONE(1234)
   ENDIF
   ::Show()
   SETAPPFOCUS( self )
   PostAppEvent( xbeBRW_ItemMarked, {::_nMaxRow, 1 },, self )
ich habe die maximale Länge ( LastRec() ) und ::_nMaxRow ist die Anzahl von Zeilen = oResult:rows.
Das ganze funktioniert aber warum benötigt er eine "Denkpause" bei > 500000 ?

müsste er mit OFFSET nicht immer gleich schnell sein ?

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Do, 19. Jul 2012 8:06
von georg
Hallo, Jimmy -


das sind wieder Deine esoterischen Fragen ...

Jeder Server implementiert das anders. Generell kann man aber davon ausgehen, dass ein SELECT * FROM table ORDER BY sortierung LIMIT x OFFSET y immer dann schnell ist, wenn das angeforderte ORDER BY durch einen Index (z.B. PRIMARY KEY) definiert ist. In dem Fall muss "lediglich" der B-Tree (oder Äquivalent) entsprechend ausgelesen werden.

Forderst Du aber eine Sortierung an, die nicht als Index vorliegt, muss der Server quasi einen Ad-Hoc Index erstellen, auswerten, und wegwerfen. Das kann - gerade bei grösseren Datenmengen - etwas Zeit kosten.


Gruss,

Georg

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Do, 19. Jul 2012 8:38
von AUGE_OHR
georg hat geschrieben:das sind wieder Deine esoterischen Fragen ...
nö ... ich "merke" sie doch ;)
georg hat geschrieben:Generell kann man aber davon ausgehen, dass ein SELECT * FROM table ORDER BY sortierung LIMIT x OFFSET y immer dann schnell ist, wenn das angeforderte ORDER BY durch einen Index (z.B. PRIMARY KEY) definiert ist.
das ist er bei mir

Code: Alles auswählen

ORDER BY __record
p.s. LIMIT x = 20-50

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Sa, 21. Jul 2012 8:17
von AUGE_OHR
hi,

hier mal paar Zahlen
LIMIT 30 OFFSET 560788 after 5.90 Sec.
LIMIT 30 OFFSET 560758 after 4.92 Sec.
LIMIT 30 OFFSET 560728 after 3.89 Sec.
und die "Gegenprobe"
BigTable_OFFSET.PNG
BigTable_OFFSET.PNG (31.01 KiB) 14703 mal betrachtet
man sieht also pgAdmin.EXE ist auch nicht schneller ... es liegt also nicht an meinem Code.

aber woran dann ? ich bin doch auf "__record" welcher der "PRIMARY KEY" ist und "ORDER BY __record"

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mo, 23. Jul 2012 13:07
von UliTs
Bei detr Gegenprobe sehe ich nirgends das "order by" :-9

Uli

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Di, 24. Jul 2012 1:31
von AUGE_OHR
UliTs hat geschrieben:Bei detr Gegenprobe sehe ich nirgends das "order by" :-9
ich bin doch auf "__record" welcher der "PRIMARY KEY" ist und "ORDER BY __record"
ist der beim öffnen durch pgAdmin.EXE dann nicht auch gleich "aktive" ?
ich habe wegen pgAdmin.EXE ja einen neuen Thread angefangen weil u.U. viel langsamer ...

Der "grosse" OFFSET ist "nur" ein "Power" Problem denn auf dem Notebook (2630QM / SSD) ist das kein Thema mehr.
für das Netzwerk heisst das wohl auch das der Server "reichlich Power" haben sollte für Anfragen ...

nachdem also nun wohl feststeht das grosse OFFSET nicht die "optimale" Lösung ist frage ich mich wie/was pgDBE wohl macht ...
der "Import" der DBF in der "lates" v.051 nutzt nun auch "Sequence" sodass pgDBE die wohl nun (hoffentlich) "richtig" öffnen kann und ich damit testen kann.

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Di, 24. Jul 2012 10:21
von bgl
Könnte eine Frage der Cache-Einstellungen sein. Dazu will ich mich aber eigentlich nicht äussern, weil ich zugeben muss, dass mir die Konfigurationseinstellungen von PostgreSQL immer wieder selber Kopfschmerzen machen.

Eine Anmerkung aber hier noch, die wichtig ist und vielleicht (vielleicht!) mit dem Problem zu tun hat:

LIMIT/OFFSET sollten niemals ohne ORDER BY verwendet werden.

Verwendest du kein ORDER BY, so sortiert der Server nach Bauchgefühl. Das kann auch mal bei jedem Zugriff anders aussehen. MySQL ist da fast zuverlässig (edit: sortiert scheinbar auch mittlerweile nach Änderungsdatum, ich bin mir aber fast sicher das war mal anders), PostgreSQL ist da skrupelloser und würfelt die Sortierung nach Änderungsdatum der Zeilen und ähnlichem zusammen!

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Di, 24. Jul 2012 11:57
von UliTs
AUGE_OHR hat geschrieben:...ist der beim öffnen durch pgAdmin.EXE dann nicht auch gleich "aktive" ?
Wie bgl schon schrieb, ist das Ganze ohne Angabe einer Sortierung sinnlos.
Ist es denn mit Angabe einer Sortierung, zu der es einen Index gibt, in der Gegenprobe schnell?

Uli

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Di, 24. Jul 2012 20:43
von AUGE_OHR
hi,

Frage : wenn ich eine Table öffne die einen "PRIMARY KEY" hat wird der als "ORDER" genommen oder muss ich das Field, hier __record, noch extra als "ORDER BY " angeben ?

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Di, 24. Jul 2012 21:21
von georg
AUGE_OHR hat geschrieben:hi,

Frage : wenn ich eine Table öffne die einen "PRIMARY KEY" hat wird der als "ORDER" genommen oder muss ich das Field, hier __record, noch extra als "ORDER BY " angeben ?
Hallo, Jimmy -


das ist Dein Denken in SELECT-Bereichen.

Wenn Du eine Tabelle VERWENDEST, entscheidest Du darüber, wie. Bei INSERT und UPDATE wird über den PRIMARY KEY im Hintergrund geprüft. Wenn Du ein SELECT ausführst, MUSST Du angeben, welche Sortierung (ORDER BY) Du haben willst. Siehe dazu auch Benjamins (bgl) Statement zu LIMIT/OFFSET.

Anders formuliert: alle Indexe (dazu gehört PRIMARY KEY) werden im Hintergrund immer geöffnet, um aktualisiert zu werden. Die Zugriffsreihenfolge muss IMMER explizit angefordert werden.


Gruss,

Georg

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Di, 24. Jul 2012 22:14
von UliTs
UliTs hat geschrieben:Ist es denn mit Angabe einer Sortierung, zu der es einen Index gibt, in der Gegenprobe schnell?
Uli
Und Jimmy, wie schaut es aus?

Uli

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Di, 24. Jul 2012 23:10
von AUGE_OHR
UliTs hat geschrieben:
UliTs hat geschrieben:Ist es denn mit Angabe einer Sortierung, zu der es einen Index gibt, in der Gegenprobe schnell?
Uli
Und Jimmy, wie schaut es aus?
nix, wie ich sagte er "ist" auf dem "PRIMARY KEY" der "__record" heisst und der "natürlichen" Sortierung entspricht.

allerdings ist mir das mit pgAdmin.EXE selbst, auf dem Notebook, noch nicht klar warum er manchmal extrem langsam ist ... gegenüber einem P4 3Ghz

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Di, 24. Jul 2012 23:26
von UliTs
AUGE_OHR hat geschrieben:nix, wie ich sagte er "ist" auf dem "PRIMARY KEY" der "__record" heisst und der "natürlichen" Sortierung entspricht...
Ich deute mal Deine Antwort so, dass Du es inzwischen ausprobiert hast, aber es trotzdem langsam ist :-( .
Mysteriös 8) . Da liebe ich doch den ADS :D .

Uli

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 25. Jul 2012 0:32
von AUGE_OHR
UliTs hat geschrieben:Ich deute mal Deine Antwort so, dass Du es inzwischen ausprobiert hast, aber es trotzdem langsam ist :-( .
ok hier nun die Snapshots
Ohne_ORDER_BY.PNG
Ohne_ORDER_BY.PNG (68.55 KiB) 14644 mal betrachtet
Mit_ORDER_BY.PNG
Mit_ORDER_BY.PNG (63.52 KiB) 14644 mal betrachtet
FS_Mit_ORDER_BY.PNG
FS_Mit_ORDER_BY.PNG (55.36 KiB) 14644 mal betrachtet
reicht dir das als Beweis :!:

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 25. Jul 2012 2:04
von bgl
Also, dass das gesamt-select bei der Datenmenge gerade mit pgAdmin etwas träge wird ist nicht besonders überraschend. Die Daten müssen zwischen pgAdmin und dem PostgreSQL-Server hin- und hergeschoben werden, irgendwo gecached werden etc... und pgAdmin ist nicht unbedingt für Geschwindigkeit berühmt, aber dafür ist es auch eigentlich nicht gedacht.

Interessant wäre, wie es mit LIMIT/OFFSET in Verbindung mit ORDER BY aussieht, ob du da nach wie vor Probleme hast, wenn du "weiter hinten" in der Tabelle bist.

Und es gibt keine natürliche Sortierung nach dem PRIMARY KEY! Nicht vorhanden! Sortiert wird, soweit das die praktische Verwendung angeht, nach dem Zufallsprinzip, wenn du kein ORDER BY verwendest.

Das heisst, dass es sein kann, dass du mit LIMIT 50 OFFSET 0 die ersten 50 Zeilen abrufst, beim nächsten Aufruf mit LIMIT 50 OFFSET 50 aber 50 Zeilen aus einer VÖLLIG anderen Ecke der Tabelle geliefert bekommst, oder sogar die gleichen wie vorher.

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 25. Jul 2012 2:46
von AUGE_OHR
bgl hat geschrieben:Interessant wäre, wie es mit LIMIT/OFFSET in Verbindung mit ORDER BY aussieht, ob du da nach wie vor Probleme hast, wenn du "weiter hinten" in der Tabelle bist.
mit pgAdmin.EXE oder PGu.EXE ?
PGu.EXE auf dem Notebook < 1 sec (local) :badgrin:
bgl hat geschrieben:Und es gibt keine natürliche Sortierung nach dem PRIMARY KEY! Nicht vorhanden! Sortiert wird, soweit das die praktische Verwendung angeht, nach dem Zufallsprinzip, wenn du kein ORDER BY verwendest.
ich habe die Table gerade vorher erstellt und alle Datensätze importiert wobei ich nextval(***__record) zum hochzählen verwende und "__record" der "PRIMARY KEY" ist.
deshalb sprach ich von "natürlicher Sortierung" -> "__record" Type "serial"

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 25. Jul 2012 4:14
von bgl
AUGE_OHR hat geschrieben:
bgl hat geschrieben:Interessant wäre, wie es mit LIMIT/OFFSET in Verbindung mit ORDER BY aussieht, ob du da nach wie vor Probleme hast, wenn du "weiter hinten" in der Tabelle bist.
mit pgAdmin.EXE oder PGu.EXE ?
PGu.EXE auf dem Notebook < 1 sec (local) :badgrin:
bgl hat geschrieben:Und es gibt keine natürliche Sortierung nach dem PRIMARY KEY! Nicht vorhanden! Sortiert wird, soweit das die praktische Verwendung angeht, nach dem Zufallsprinzip, wenn du kein ORDER BY verwendest.
ich habe die Table gerade vorher erstellt und alle Datensätze importiert wobei ich nextval(***__record) zum hochzählen verwende und "__record" der "PRIMARY KEY" ist.
deshalb sprach ich von "natürlicher Sortierung" -> "__record" Type "serial"
Selbst dann brauchst du aber ORDER BY __record, wenn du die Daten sortiert auslesen willst. Und im Fall von LIMIT/OFFSET ist das quasi zwingend notwendig, weil du sonst zufaellige Tabellenschnipsel in LIMIT-Grösse erhalten kannst.

Das schlimmste daran: es mag im Test sauber laufen, dann wird es in einer Multi-User-Umgebung genutzt, Datensätze werden parallel geändert und auf einmal wird die Sortierung nach einem "praktischeren" Kriterium (aus Sicht des Servers, nicht aus der des Programms/Anwenders) vorgenommen und dein Programm ist ganz wo anders dran, als du es erwartet hättest.

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 25. Jul 2012 5:26
von AUGE_OHR
bgl hat geschrieben:Das schlimmste daran: es mag im Test sauber laufen, dann wird es in einer Multi-User-Umgebung genutzt, Datensätze werden parallel geändert und auf einmal wird die Sortierung nach einem "praktischeren" Kriterium (aus Sicht des Servers, nicht aus der des Programms/Anwenders) vorgenommen und dein Programm ist ganz wo anders dran, als du es erwartet hättest.
ok aber das ist mit DBF Dateien genau so ;)
nun habe ich für die "Kommunikation" zwischen den User ein Mail-System ... zunächst für den User gedacht.
im selben System verschicke ich aber auch "System" Nachrichten und kann nun, per COPY_DATA, vom Mail-System meine Applicationen "benachrichtigen" z.b. Refresh ...



als PG Newbie geht es mir zunächst um das ausloten was PG kann, was "native" möglich ist und am Ende steht pgDBE

mit kleinen Table ist das nun alle kein Problem aber bei grossen wissen wir ja nun das ein grosser OFFSET viel "Power" braucht.
was auf einem P4 3GHz > 10 Sec. benötigt geht mit einem i7-2630QM in < 0.5 Sec. DAS kann ich vorführen ;)
das gilt nun für die "native" Version und pgAdmin.EXE ... und was ist mit pgDBE ?

damit ich das prüfen kann musste ich mir erstmal die Grundlagen reinziehen und meine DBF -> PG Import Schnittstelle so anpassen
damit pgDBE die "frisst" da das "DbfUpsize.EXE" meine OEM DBF "so" nicht verarbeiten kann.

ich denke ich werde diesen Thread auch auf [erledigt] setzten.
danke an alle die hier geantwortet haben.

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 25. Jul 2012 11:42
von UliTs
AUGE_OHR hat geschrieben:reicht dir das als Beweis :!:
Was hast Du denn schon wieder für ein Problem?
Wofür soll denn das ein Beweis sein???
Was haben denn Deine Bilder mit LIMIT und OFFSET zu tun?
Sieht mal wieder nach einem Apfel/Birnenproblem aus.

Uli

Re: PostgreSQL LIMIT / OFFSET

Verfasst: Mi, 25. Jul 2012 11:48
von brandelh
AUGE_OHR hat geschrieben:mit kleinen Table ist das nun alle kein Problem aber bei grossen wissen wir ja nun das ein grosser OFFSET viel "Power" braucht.
was auf einem P4 3GHz > 10 Sec. benötigt geht mit einem i7-2630QM in < 0.5 Sec. DAS kann ich vorführen ;)
die Power wird bei einem SELECT verschwendet, der eine so große Treffermenge erzeugt, der OFFSET verringert dann eher die Rückgabemenge.
Wenn man aber 10 solcher Teile braucht, braucht man auch 10 mal die Suche. Am Anfang braucht man ja nicht alles durchsuchen, aber mit steigendem OFFSET wird es immer mehr und der Anfang ist immer dabei ... (außer der SERVER könnte erkennen was er schon durchsucht hat und den Befehl direkt auf dem OFFSET weiterführen :?: )

TIP: Wenn der schnellste Rennwagen zu langsam wird, sollte man über einen kürzeren Weg nachdenken :badgrin: