PDA

View Full Version : SQL Order by wird vorgezogen, kann ich das ändern?



Robi
18-12-25, 09:00
Moin zusammen

Ist mir schon öfter aufgefallen:

ich mache einen
strsql
select * from datei where feld = wert

Keine Millisekunde später stehen 6 Sätze am Bildschirm

Das passt so für mich nicht, also nochmal

select * from datei where feld = wert order by xyfeld (z.B. Betrag)
Bei rd. 6 Mio Sätzen warte ich 8-10 Sekunden auf die Anzeige.

Ja, es gibt keinen Index auf Betrag.
Aber erst der select, dann der sort (von 6 Sätzen) kann doch nicht so wild sein.
Ich vermute das er erst sortiert und dann selektiert.
Kann ich das 'einstellen'

Schöne Feiertage/guten Rutsch
Robi

B.Hauser
18-12-25, 10:27
Gibt es denn einen Index, der das FELD als erste Schlüssel-Spalte hat?

Robi
18-12-25, 11:21
Nein, es gibt für das order By Feld keinen Index

Wird in der Anwendung auch nicht gebaucht.
Aber für irgend welche manuellen Kontrollen ist das halt ganz nett auch mal ein order by ohne Index zu machen.
wie gesagt, 6 !!! Sätze

B.Hauser
18-12-25, 11:45
Ich denke zwar nicht, dass es viel bringt ... aber füge mal spasseshalber am Ende des SQL Statements:
OPTIMIZE FOR 6 ROWS
an.
6 ist nur eine kleine Zahl, die bewirkt, dass das *FIRSTIO Optimierungsziel verwendet wird.

Um eine detaillierte Analyse zu machen müsste ich tiefer einsteigen.

Fuerchau
18-12-25, 13:44
Bei Verwendung von Order By hilft auch kein Optimize, wobei ich mit "optimize for " noch nie einen Unterschied feststellen konnte.

Von der Reihenfolge wird der Order By erst am Schluss eines Selects ausgeführt, da das Ergebnis sortiert wird.
Entscheidend ist die Where-Klausel, dass es für diese einen Index gibt.

Dass dein 1. Versuch ohne Order By so schnell war, liegt u.U. am Cache, dass die Tabelle weitestgehend bereits im Speicher liegt. Das Ergebnis wird dann nach Satznummer präsentiert.
Ggf. ist auch das Parallelfeature installiert, wenn es inzwischen sowieso nicht schon Standard ist, was die Ausführung parallelisiert.

Der Optimizer versucht allerdings, wenn Order By und Where-Klausel passen, hier dieselben Felder, wird tasächlich ein temporärer Index erstellt, der dann durchsucht wird. Step 1 ist dann langsam, da dies nicht parallelisiert werden kann.

Visual Explain ist da schon mal hilfreich.

Wenn dir die Sortierung nicht passt, kannst du Ergebnisse auch per Multiple Row Fetch in ein Array laden und anschließend den SORTA bemühen:
https://www.ibm.com/docs/en/i/7.1.0?topic=statement-multiple-row-fetch-using-host-structure-array

Hier wird das Beispiel mit COBOL gezeigt, aber mit ILERPG und Qualaified sowie DIM klappt das auch.
Und der SORTA kann dann auf einzelnen Felder das komplette Array sortieren.
Das klappt auch mit einem %SUBARR, da das Array ja nicht komplett gefüllt werden muss.

Meist reicht da eine DS mit bis zu 16MB aus, wenn man nicht gerade einen "Select * ..." fabriziert.

Robi
18-12-25, 14:06
Bei dem Kunden haben die PF einen Key.

Das Feld, das ich selektiere ist das 1. Key Feld der PF.
Auf dem Order By Feld ist kein Index

der erste Aufruf ging schnell weil es den Index gibt

Habe das Verhalten eigendlich immer, wenn ich 'nachträglich' ein vorher angezeigtes Ergebnis sortiere.

Teste morgen den Optimize (wobei ich ja nur weis wieviel es sind, wenn ich vorher den order by vergesse)

Fuerchau
18-12-25, 14:27
Der Index wird ignoriert, wenn die Where-Klauses das Feld des Index nicht verwendet.

Ggf. kannst du noch einen Trick anwenden:

select count(*) over() Anzahl
,a.*
from MyTable a
where ....

Der Count liefert dir bei jedem Satz die Anzahl des Ergebnisses, dafür muss eher ein Tablescan durchgeführt werden, bevor der OrderBy angewendet werden kann.
Diese sog. Window-Funktionen sind besonders gut optimiert.