Seite 1 von 1

PostgreSQL "MOVE"

Verfasst: Mi, 01. Aug 2012 23:48
von AUGE_OHR
hi,

wenn ich folgenden Code in pgAdmin.EXE eingebe

Code: Alles auswählen

BEGIN WORK;
DECLARE liahona CURSOR FOR SELECT * FROM fsicher;
MOVE FORWARD 500000 IN liahona;
FETCH 1 FROM liahona;
CLOSE liahona;
COMMIT WORK;
bekomme ich als Antwort
Abfrageergebnis mit 1 Zeilen wurde unterdrückt.

Abfrage war erfolgreich nach 1297 ms. Keine Zeilen geliefert.
es wird bei MOVE ja auch gesagt
MOVE positioniert einen Cursor, ohne Daten zu lesen. MOVE funktioniert genauso wie der Befehl FETCH,
außer dass es nur den Cursor positioniert und keine Daten zurück gibt.
aber ich verwende doch, wie im Demo zu MOVE, auch FETCH und "müsste" damit doch eine Anzeige bekommen ... :banghead:

p.s. wenn er wirklich auf "der" Position +500000 stehen sollte wäre die "Zeit" dafür nicht schlecht ( P4 )

Re: PostgreSQL "MOVE"

Verfasst: Do, 02. Aug 2012 0:26
von bgl
AUGE_OHR hat geschrieben:hi,

wenn ich folgenden Code in pgAdmin.EXE eingebe

Code: Alles auswählen

BEGIN WORK;
DECLARE liahona CURSOR FOR SELECT * FROM fsicher;
MOVE FORWARD 500000 IN liahona;
FETCH 1 FROM liahona;
CLOSE liahona;
COMMIT WORK;
bekomme ich als Antwort
Abfrageergebnis mit 1 Zeilen wurde unterdrückt.

Abfrage war erfolgreich nach 1297 ms. Keine Zeilen geliefert.
es wird bei MOVE ja auch gesagt
MOVE positioniert einen Cursor, ohne Daten zu lesen. MOVE funktioniert genauso wie der Befehl FETCH,
außer dass es nur den Cursor positioniert und keine Daten zurück gibt.
aber ich verwende doch, wie im Demo zu MOVE, auch FETCH und "müsste" damit doch eine Anzeige bekommen ... :banghead:

p.s. wenn er wirklich auf "der" Position +500000 stehen sollte wäre die "Zeit" dafür nicht schlecht ( P4 )
Das ist eine hinterhältige Sache - nicht du bekommst ein Ergebnis, sondern pgAdmin - und pgAdmin wills dir nicht anzeigen (Folgebefehl nach dem Ergebnis könnte der Grund sein, sicher bin ich mir grad nicht).
in psql würdest du dein Ergebnis vermutlich auch zu Gesicht bekommen, pgAdmin erzählt dir nur, dass es irgendwo zwischendrin eins gab.
Dein SQL ist also okay, dein Werkzeug will dich ärgern :-D

Re: PostgreSQL "MOVE"

Verfasst: Do, 02. Aug 2012 1:14
von AUGE_OHR
bgl hat geschrieben:Dein SQL ist also okay, dein Werkzeug will dich ärgern :-D
das ist gemein ... wie soll man auf so was kommen #-o

ok nachdem ich es geschafft habe mich mit PSql.EXE einzuloggen gab es beim FETCH auch eine "Ausgabe".
ich habe ihm doch MOVE 500000 eingegeben aber er steht "nur" auf 354317 ?

Re: PostgreSQL "MOVE"

Verfasst: Do, 02. Aug 2012 1:18
von bgl
AUGE_OHR hat geschrieben:
bgl hat geschrieben:Dein SQL ist also okay, dein Werkzeug will dich ärgern :-D
das ist gemein ... wie soll man auf so was kommen #-o

ok nachdem ich es geschafft habe mich mit PSql.EXE einzuloggen gab es beim FETCH auch eine "Ausgabe".
ich habe ihm doch MOVE 500000 eingegeben aber er steht "nur" auf 354317 ?
ORDER BY ist dein Freund...

Re: PostgreSQL "MOVE"

Verfasst: Do, 02. Aug 2012 1:22
von AUGE_OHR
bgl hat geschrieben:ORDER BY ist dein Freund...
#-o ok das war es ... DANKE !
WOW !!!
so und nun muss ich mal sehen ob ich das in der "native" Version hin bekomme ...

Re: PostgreSQL "MOVE"

Verfasst: Do, 02. Aug 2012 1:27
von bgl
AUGE_OHR hat geschrieben:
bgl hat geschrieben:ORDER BY ist dein Freund...
#-o ok das war es ... DANKE !
WOW !!!
so und nun muss ich mal sehen ob ich das in der "native" Version hin bekomme ...
Immerhin hast du jetzt eine Vorstellung, warum ich ORDER BY so sehr betone ;-)

Re: PostgreSQL "MOVE"

Verfasst: Do, 02. Aug 2012 1:59
von AUGE_OHR
bgl hat geschrieben:Immerhin hast du jetzt eine Vorstellung, warum ich ORDER BY so sehr betone ;-)
ja ... wieder nicht dran gedacht ...

also mit MOVE kann ich scheinbar "ähnlich" wie mit OFFSET arbeiten und FETCH nAnzahl ist "ähnlich" LIMIT

bei FETCH steht nun

Code: Alles auswählen

FETCH cursor INTO ziel;
also ist es nicht ein "übliches" Result ... oder ?

Re: PostgreSQL "MOVE"

Verfasst: Do, 02. Aug 2012 2:39
von AUGE_OHR
AUGE_OHR hat geschrieben:bei FETCH steht nun

Code: Alles auswählen

FETCH cursor INTO ziel;
also ist es nicht ein "übliches" Result ... oder ?
die Frage ist eher wie komme ich an "ziel" ?

Code: Alles auswählen

PRIVATE ziel := ""

cVar4 := "FETCH "+cLimit+" FROM liahona INTO ziel"    
cVar4 := "FETCH "+cLimit+" FROM liahona INTO 'ziel' "    
cVar4 := "FETCH "+cLimit+" FROM liahona INTO "+ ziel    
cVar4 := "FETCH "+cLimit+" FROM liahona INTO "+ &ziel    
das haut alles nicht in ... "denke" ich
wie wäre denn die "richtige" Xbase++ Syntax die bei SQL "funktioniert" ?

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 1:24
von AUGE_OHR
hi,

also das mit dem INTO war der falsche Weg ... :banghead:

nun funktioniert es ja so weit mit CURSOR / MOVE / FETCH ... vorwärts ...
MOVE [ FORWARD | BACKWARD | RELATIVE ] [ anzahl | ALL | NEXT | PRIOR ] { FROM | IN
} cursor
die Frage ist ob ich von der "aktuellen" Position mich "bewege" ?
den Kommentar zu RELATIVE in FETCH hab ich gelesen also werde ich mich auf FORWARD | BACKWARD konzentrieren.

Frage : ist eine negative "anzahl" <-> BACKWARD ?

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 4:33
von AUGE_OHR
hi,
ich habe es ausprobiert und es scheint "die" Lösung zu sein :blob8:
auch bei > 560000 Record kein Problem beim Browse mit dem P4 (!), alles deutlich < 1 sec !!!

und das MOVE ist der Hammer was die Geschwindigkeit angeht und man "steht" dort wo man mit einem FETCH anfangen will.
Georg hatte ja mal die "Mächtigkeit" von CURSOR angedeutet aber erst das MOVE macht es interessant für Xbase++ User.
Frage : ist eine negative "anzahl" <-> BACKWARD ?
diese Frage erübrigt sich da ich BACKWARD nicht benötige. vielmehr kann ich mein cOFFSET verwenden und lande an der gewünschten Stelle

Schlussfolgerung : auch MOVE geht von "vorne" los ... ist aber viel schneller auf der OFFSET Position

nun wäre es ja zu schön um war zu sein den dies galt für "ORDER BY __record"
sobald ich auf eine andere Order gehe "merke" ich wie er langsamer wird ... insgesamt aber trotzdem viel schneller als LIMIT

Frage : was ist der (mögliche) Grund für diese Verhalten ?

... ich "denke" so langsam komme ich dahinter ;)

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 5:02
von Martin Altmann
Moin,
AUGE_OHR hat geschrieben:sobald ich auf eine andere Order gehe "merke" ich wie er langsamer wird ... insgesamt aber trotzdem viel schneller als LIMIT

Frage : was ist der (mögliche) Grund für diese Verhalten ?
ganz einfach - Du wirst dem Server nicht gesagt haben, dass Du über diese Spalte einen Index haben möchtest!

Viele Grüße,
Martin

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 5:26
von AUGE_OHR
Martin Altmann hat geschrieben: ganz einfach - Du wirst dem Server nicht gesagt haben, dass Du über diese Spalte einen Index haben möchtest!
AUGE_OHR hat geschrieben:sobald ich auf eine andere ORDER BY*** gehe ...
*** korrigiert

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 5:28
von Martin Altmann
:?:
Hast Du jetzt einen Index auf der Spalte und es geht schneller? Ich verstehe Deinen Hinweis nicht so richtig.

Viele Grüße,
Martin

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 5:38
von AUGE_OHR
Martin Altmann hat geschrieben::?:
Hast Du jetzt einen Index auf der Spalte und es geht schneller? Ich verstehe Deinen Hinweis nicht so richtig.
ich habe jetzt IMMER ein "ORDER BY ".
nun bei einigen ist er "langsamer" als bei anderen von der selben Table.

allerdings ist das, wie Georg zu sagen würde, eher wieder eine esoterische Frage denn auch so ist "die" Lösung noch schneller als alles andere was ich ausprobiert habe ( auf einem P4 )

ich muss den "modi stru" Teil mal fertig machen und ein neues Update von PGu.EXE liefern ...

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 5:51
von Martin Altmann
Jimmy,
ORDER BY hat nichts damit zu tun, ob es in der Datenbank auch einen passenden Index gibt!
Gibt es einen, wird der bei der Anweisung auch genommen und es geht schneller.
Gibt es keinen, wird (je nach SQL-Server-Software) unterschiedlich verfahren:
Der eine gibt alles passende aus der Datenbank zurück und sortiert es entsprechend Deiner ORDER BY-Clause "in memory", bevor es Dir das als Deine Ergebnismenge zurückgibt.
Der nächste erzeugt einen temporären Index entsprechend Deiner ORDER BY-Clause und gibt Dir dann Deine Ergebnismenge zurück und löscht den temporären Index wieder.
Der nächste analysiert erst Mal, was schneller ginge und verfährt dann so (kleine Menge an Datensätzen: "in memory" sortieren, sonst temporären Index anlegen).
Manch ein System hält die temporären Indexe auch ein wenig länger vor und löscht sie nicht sofort.

Lege mal ein Index auf Dein anderes ORDER BY-Kriterium und prüfe, ob es jetzt schneller geht.
Aber wie schon häufiger gesagt: Nicht zu viele Indexe anlegen!

Viele Grüße,
Martin

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 7:40
von brandelh
Es kommt wie immer auf die Datenmenge an.
Wenn eine Tabelle 1000 Datensätze hat, geht das ohne Optimierung immer schnell.
Bei Firmen mit 10 Millionen Datensätzen gibt es extra einen Datenbank Administrator der dafür sorgt,
dass die Zugriffe über Indexe auf dem SQL Server optimiert werden.
Damit meine ich nicht, komplexe Indexe zum Sortieren wie unter Xbase++.

Beispiel:
  • private Adresssammlung, für die paar Datensätze braucht man keinen Index.
  • kleine Firma:
    5000 Artikel
    1000 Kunden
    100 Lieferanten ...
    10000 Rechnungen ...
    hier kann man sicher auch ohne Index auskommen, aber z.B. KundenID, LieferantenID, RechnungsNr wären sicherlich nicht schädlich.
  • große Firma:
    hier muss man sich überlegen nach was die Mitarbeiter suchen und schnelle Antwort brauchen:
    Adressen: PLZ, Straße, Ort, Geburtsdatum, AdressID ...
    Artikel: ID, Lieferdatum (?), Ablaufdatum (?)
    In großen Firmen wird sicher auch per Admintool (?) geprüft, wo der Server zu langsam ist um eventuell zusätzliche Indexe anzubieten.

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 7:53
von AUGE_OHR
Martin Altmann hat geschrieben:ORDER BY hat nichts damit zu tun, ob es in der Datenbank auch einen passenden Index gibt!
ich "dachte" ich hätte mittels pgAdmin.EXE "bewiesen" das es KEINEN UNTERSCHIED macht ob du einen "Index" nimmst oder die selben Fields "on-fly" im "SELECT ... ORDER BY " verwendest.
Martin Altmann hat geschrieben:Gibt es einen, wird der bei der Anweisung auch genommen und es geht schneller. ...
ich höre euch das immer wieder sagen, aber ich finde kein Beispiel wo ich das Gegenteil erkennen könnte.

vielleicht muss ich das System anders "stressen" damit ich den Effekt erkenne, aber beim "blättern" und "positionieren" erziele ich keine Zeit Unterschiede wie es "theoretisch" ja sein sollte.

ich habe nun im PostgeSQL Handbuch durchaus Sachen gesehen, so "verschachtelt", das es vielleicht in solchen Fällen einen Vorteil bringen könnte, aber so was kann "ich" nicht zusammenbauen und pgDBE ...

pgDBE soll doch "was einfaches" werden und der Xbase++ soll "vorhandenes" verwenden können.
wir sind gewohnt mit DBSEEK(), SKIP() und GOTO() zu arbeiten was ja nun "Satz-orientiert" ist.

wenn ich aber pgDBE versucht an dem "alten" Konzept von Phil Ide festzuhalten statt sich was "einfallen" zu lassen wie man das ganze "optimieren" könnte dann habe ich Zweifel am "Index" Konzept mit pgDBE ... wenn es keine Vorteil bringt ?!

Ein Data-Dic mit INDEXKEY(), was man zur Laufzeit "verändern" kann, wäre eine viel "wartungsfreundlichere" Lösung und IMHO "genau so schnell"


***


nein es ist wieder das alte Spiel das er beim "MOVE" eben doch immer von "vorne" losgeht
wenn ich __record verwende wären die Daten wirklich "hintereinander".
bei einer "ORDER BY " auf "PRIMARY KEY" Field, die ja auch "hintereinander" liegen "sollten" ist es ähnlich schnell.
wie schnell ... hier paar Zahlen :
finsh request after 0.01 Sec.
Browse Pop-Up after 0.03 Sec.

SELECT
a.fkdnr,a.fmonat,a.fnummer,a.fartnr,a.fartikel,a.fanzahl,a.feinh,a.bpreis,a.fstu
eck,a.fmwst,a.mschl,a.fpreis,a.skonto,a.fjahr,a.fftag,a.ffmonat,a.ffjahr,a.ftext
,a.dflag,a.liefnr,a.lflag,a.rechwahl,a.aqnr,a.__deleted,a.__record,a.__rowversio
n,a.__keyversion,a.__lock_owner FROM fsicher AS a ORDER BY __record LIMIT 25
MOVE 0

BEGIN WORK : 0.00 Sec.
DECLARE MyCursor: 0.00 Sec.
FETCH FORWARD : ORDER BY __record after 0.00 Sec.
Get Result : 0.03 Sec.
CLOSE MyCursor : 0.00 Sec.
COMMIT WORK : 0.00 Sec.

Index : SELECT __record FROM fsicher AS a ORDER BY __record
BEGIN WORK : 0.00 Sec.
DECLARE MyCursor: 0.00 Sec.
MOVE FORWARD : 0.00 Sec.
FETCH FORWARD : ORDER BY __record after 0.00 Sec.
Get Result : 0.04 Sec.
CLOSE MyCursor : 0.00 Sec.
COMMIT WORK : 0.00 Sec.

BEGIN WORK : 0.00 Sec.
DECLARE MyCursor: 0.00 Sec.
MOVE FORWARD : 0.00 Sec.
FETCH FORWARD : ORDER BY __record after 0.00 Sec.
Get Result : 0.05 Sec.
CLOSE MyCursor : 0.00 Sec.
COMMIT WORK : 0.00 Sec.

BEGIN WORK : 0.03 Sec.
DECLARE MyCursor: 0.00 Sec.
MOVE FORWARD : 0.00 Sec.
FETCH FORWARD : ORDER BY __record after 0.00 Sec.
Get Result : 0.03 Sec.
CLOSE MyCursor : 0.00 Sec.
COMMIT WORK : 0.00 Sec.

BEGIN WORK : 0.00 Sec.
DECLARE MyCursor: 0.00 Sec.
MOVE FORWARD : 0.00 Sec.
FETCH FORWARD : ORDER BY __record after 0.00 Sec.
Get Result : 0.03 Sec.
CLOSE MyCursor : 0.00 Sec.
COMMIT WORK : 0.00 Sec.
normales "blättern" im Browse dauert 0.03-0.04Sec und ein DbGoBottom() 0.05sec ... und das auf dem P4 3GHz und > 550000 Record

aber wie schon gesagt die Sache sieht ganz anders aus wenn ich

Code: Alles auswählen

ORDER BY __order_custa_custa
und/oder
ORDER BY CustNo
denn das muss ja nicht mehr die "natürliche" Reihenfolge sein.

hier ist nun wieder "Power" angesagt den auch das "MOVE" reagiert da leider nur mit "Power"
create Index 572596 Records 44.22 Sec.

nIsRec 101 field 23678 nOutRec 101
change to ORDER BY fartikel WHERE Recno 101

SELECT
a.fkdnr,a.fmonat,a.fnummer,a.fartnr,a.fartikel,a.fanzahl,a.feinh,a.bpreis,a.fstu
eck,a.fmwst,a.mschl,a.fpreis,a.skonto,a.fjahr,a.fftag,a.ffmonat,a.ffjahr,a.ftext
,a.dflag,a.liefnr,a.lflag,a.rechwahl,a.aqnr,a.__deleted,a.__record,a.__rowversio
n,a.__keyversion,a.__lock_owner FROM fsicher AS a ORDER BY fartikel LIMIT 25
MOVE 100

BEGIN WORK : 0.00 Sec.
DECLARE MyCursor: 0.07 Sec.
MOVE FORWARD : 38.26 Sec.
FETCH FORWARD : ORDER BY fartikel after 0.00 Sec.
Get Result : 0.03 Sec.
CLOSE MyCursor : 0.78 Sec.
COMMIT WORK : 0.00 Sec.

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 8:02
von AUGE_OHR
hi

erst mal sorry wenn ich zuviel "gekürzt haben sollte ...
brandelh hat geschrieben:Es kommt wie immer auf die Datenmenge an.
YUP
brandelh hat geschrieben:Bei Firmen mit 10 Millionen Datensätzen gibt es extra einen Datenbank Administrator der dafür sorgt,
dass die Zugriffe über Indexe auf dem SQL Server optimiert werden.
...
In großen Firmen wird sicher auch per Admintool (?) geprüft, wo der Server zu langsam ist um eventuell zusätzliche Indexe anzubieten.[/list]
Ja soweit ist es mir schon klar das "zusätzliche" Optimierung noch was bringen könnten ...
aber über "ORDER BY __record" ist er 80x schneller ?! ( 0.05 -> 40 Sec. )

und es ist ja wieder die "Bewegung" welche so viel Zeit kostet ... ok, auf dem i7 < 1sec mit "Power"

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 8:40
von georg
Hallo,


da wir auf unterschiedliche SQL-Server zugreifen, können gewisse Fragen (die ich dann als "esoterisch" kennzeichne) nur bedingt beantwortet werden.

Mein häuslicher MySQL-Server läuft auf einem Ready NAS+ mit einem ARM Prozessor unter Linux (ist noch Version 5.0.x von MySQL).

Jetzt war ich dort mit den Ergebnissen nicht zufrieden und habe mal mein SELECT Statement mittels EXPLAIN über die MySQL Konsole auf dem NAS abgesetzt:

Code: Alles auswählen

EXPLAIN SELECT * FROM table ORDER BY feld1, feld2
Anzumerken ist, dass es einen Index table01 über (feld1, feld2) gibt. Der Explain verwies darauf, dass KEIN Index verwendet wird.

Aha! habe ich mir gesagt, und im SELECT den Index erzwungen:

Code: Alles auswählen

EXPLAIN SELECT * FROM table FORCE INDEX (table01) ORDER BY feld1, feld2
Das war MySQL immer noch egal. Erst als ich den SELECT dieser Art einschränkte:

Code: Alles auswählen

EXPLAIN SELECT * FROM table ORDER BY feld1, feld2 LIMIT 10
wurde der Index verwendet (obwohl nicht angegeben! spricht für den Opimizer). Erstaunlicherweise funktioniert das solange, wie der LIMIT Wert unter der Satzanzahl liegt. Ist der Wert in der LIMIT Clause grösser oder gleich der Satzanzahl, wird auf den Index nicht zurückgegriffen.

Da ich gerade in Experimentierlaune war, habe ich ein paar andere SELECTs noch durchprobiert:

Code: Alles auswählen

SELECT feld1 FROM table ORDER BY feld1, feld2 LIMIT 10
=> Laufzeit 0.05 Sekunden

Code: Alles auswählen

SELECT feld1, feld2 FROM table ORDER BY feld1, feld2 LIMIT 10
=> Laufzeit 0.10 Sekunden

Code: Alles auswählen

SELECT feld1, feld2, feld3 FROM table ORDER BY feld1, feld2 LIMIT 10
=> Laufzeit 0.15 Sekunden

Die Zeiten sind nicht linear angestiegen, aber fast linear. Ich hatte ja schon mehrfach darauf hingewiesen, dass es z.B. bei einem Browse sinnvoll ist, nur die benötigten Felder anzufordern und nicht mit * alle Felder (inclusive BLOB, TEXT, etc.) anzufordern.

Dies scheint mein Test zu unterstreichen, also werde ich wohl noch etwas an meinem Code arbeiten müssen in Bezug auf Optimierungen.


Jetzt komme ich zum entscheidenden Teil:

diese Ausführungen gelten für MySQL 5.0.x unter Linux. Die Versionen 5.5.x bzw. 5.6.x verhalten sich möglicherweise anders, auch abhängig vom Betriebssystem und von der Prozessorleistung her.

Es macht auf jeden Fall Sinn, sich mit dem Verhalten des Servers bei verschiedenen Konstellationen auseinanderzusetzen und festzustellen, ob es Probleme gibt. Ich hätte nie vermutete, dass bei einem uneingeschränkten Zugriff auf eine Tabelle mit vorgegebener Sortierung der Index ignoriert wird, der genau diese Sortierung abbildet. Es mag sein, dass dies ein Bug ist, der mit späteren Versionen behoben wurde, aber wir können nie ausschliessen, dass solche Bugs auch in der jetztigen Version des Servers, mit dem wir arbeiten, vorliegen und die Ergebnisse beeinflussen.


Gruss,

Georg

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 14:25
von bgl
Der Default-INDEX-typ von PostgreSQL ist ganz gut zum Zahlen sortieren, hat aber seine Schwächen wenn du TEXT felder sortierst oder gar via LIKE durchsuchst. Da gibt es dann andere Variationen, mit denen das besser funktioniert. Also ist durchaus Optimierung, die ueber einfach nur "CREATE INDEX..." in der Minimalform hinausgeht möglich.

PS: EXPLAIN lügt manchmal.

Re: PostgreSQL "MOVE"

Verfasst: Fr, 03. Aug 2012 22:39
von AUGE_OHR
hi,

das mit "EXPLAIN" sagte man mir ja schon mal, das muss ich mir noch mal genauer ansehen.
das ein "Index", obwohl "eingebunden", evtl. nicht "aktive" ist ... hm ... an so was hab ich noch gar nicht gedacht.