"Oracle Performance Problem" - SELECT row_number() over(ORDER BY xxx)

P_H_I_L

Erfahrenes Mitglied
Hallo @ all,
ich habe ein Oracle Performance Problem. Leider finde ich im Internet keine Lösung hierzu. Vielleicht kann mir jemand von euch helfen.

Ich habe eine Tabelle 5Mio Datensätze:

Die Aufgabe:
-----------------
Die Komplette Tabelle Sortieren nach Datum oder ID (Desc), dann das Ergebnis mit Filtern einschränken und anschließend von diesem Ergebnis 500 Zeilen herausschneiden.

Mein Versuch1 - zu langsam:
------------------
Code:
SELECT xxx.x1,
       xxx.y2,
  from (SELECT row_number() over(ORDER BY xxx.idnr DESC) zeilencounter,
               xxx.x1,
               xxx.x2,
          from xxx
           Where xxx.x1 = '?!'
           AND xxx.x2 = '?!'
 where zeilencounter between 0 and 500



Mein Versuch2 - zu langsam:
------------------------------------
Code:
SELECT xxx.x1,
       xxx.y2,
  from (SELECT row_number() over(ORDER BY xxx.idnr DESC) zeilencounter,
               xxx.x1,
               xxx.x2,
          from xxx
           Where xxx.x1 = '?!'
           AND xxx.x2 = '?!'
 where zeilencounter between 0 and 500


Gibt es andere Möglichkeiten um sich den Order by zu sparen?
Bei MySQL macht der Limit 0,500 es genau richtig! Erst wird gefiltert, dann wird von dem Ergebnis die Menge abgeschnitten.... Geht das bei Oracle auch? Doch nur wie?

Danke für die Hilfe...

Lg,
Phil
 
Die Funktion row_number() wird für jeden Datensatz aufgerufen. Das ist ein rechter Performance-Verlust, da dir die normale Rownum auch genügt und du keine Gruppierungen brauchst.
Nimm die Raus und arbeite stattdessen mit ROWNUM

SQL:
WHERE ROWNUM <=500

Ergibt
SQL:
SELECT *
FROM mytable
WHERE
    x1='argument1'
    AND ROWNUM <=500
ORDER BY idnr DESC
 
Zuletzt bearbeitet von einem Moderator:
Hallo,
danke für die schnelle Antwort! Doch leider ist mit deiner Lösung das Problem nicht behoben, da ich somit erst Filtere, dann 500 Treffer aus der Ergebnismenge ausschneide und diese 500 Filter dann Sortiere....

Aber was ich will: Erst sauber die Ergebnismenge filtern, diese Anschließend sortieren und aus der SORTIERTEN Menge 500 Treffer ausschneiden..

Gibts hierfür nen Lösungsansatz?

Lg,
Phil
 
sowas?
SQL:
SELECT *
FROM
	(SELECT *
	FROM mytable
	WHERE
	    x1='argument1'
	ORDER BY idnr DESC)
WHERE
	ROWNUM <=500
 
Zuletzt bearbeitet von einem Moderator:
ja genau, sowas hab ich schon versucht. :)
einzigstes Problem bei mehreren Millionen Datensätzen dauert mir der ORDER BY viel zu lange...
Aber ich denke eine andere Möglichkeit in Oracle gibt es wohl nicht oder?

Viele Grüße,
Phil
 
Oder gibt es hier DB- Einstellungen bezüglich Tablespace oder so um die Performance zu erhöhen? Evtl. ist meine DB nur falsch konfiguriert. Habt ihr bei mehreren Millionen Datensätzen auch ein Problem mit dem Order by? oder eher nicht....

Lg,
Phil
 
Also, da gibts noch diese verkompliziertheit, die ev. hilft.

Setze einen Eindeutigen Index auf die ID und die Felder die du für den Filter brauchst.

Dann mach mal sowas nachher
SQL:
SELECT
	*
FROM
	mytable AS mt
	INNER JOIN (
			SELECT /*+ INDEX_DESC(mytable myindex) */idn
			FROM mytable
			WHERE x1='argument1'
			ORDER BY idn) AS ids
		ON mt.idn = ids.idn
ROWNUM <= 500

Wenn du das ganze mal mit explain() besichtigst, sollte er eigentlich zuerst nur einen Indexscan machen und erst mit den gefilterten Werten einen Fulltablescan. Sprich, für das innere Select sollte er nur auf den Index, nicht aber auf die Tabelle zugreiffen, da der Index bereits alle Werte beinhaltet die er haben will.

Natürlich musst du dabie achten, dass die Statistiken der Indexe halbwegs aktuell sind.
 
Zuletzt bearbeitet von einem Moderator:
ok, das schau ich mir jetzt mal in ruhe an... ob es mit einem hint schneller geht. vielen dank für die idee...

sollte es nicht funktionieren, meld ich mich wieder.. :)

lg,
phil
 
so habe das prob. behoben! Vielen Dank nochmals.
Das Problem lag an einem Where Statement mit Verbindung des Order by's...

Habe das Where - Statement geändert und schon hab ich eine deutlich bessere Performance...

LG,
Phil
 

Neue Beiträge

Zurück