Ich habe ein großes Problem mit einer SQL-Anweisung in Oracle. Ich möchte die von STORAGE_DB bestellten TOP 10-Datensätze auswählen, die nicht in einer Liste aus einer anderen select-Anweisung enthalten sind.
Dieser funktioniert gut für alle Datensätze:
SELECT DISTINCT
APP_ID,
NAME,
STORAGE_GB,
HISTORY_CREATED,
TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE
FROM HISTORY WHERE
STORAGE_GB IS NOT NULL AND
APP_ID NOT IN (SELECT APP_ID
FROM HISTORY
WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009')
Aber wenn ich hinzufüge
AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC
Ich bekomme eine Art "zufällige" Platten. Ich denke, weil das Limit vor der Bestellung stattfindet.
Hat jemand eine gute Lösung? Das andere Problem: Diese Abfrage ist wirklich langsam (10k + Datensätze)
Antworten:
Sie müssen Ihre aktuelle Abfrage wie folgt in die Unterabfrage einfügen:
Oracle wendet Rownum auf das Ergebnis an, nachdem es zurückgegeben wurde.
Sie müssen das Ergebnis filtern, nachdem es zurückgegeben wurde, daher ist eine Unterabfrage erforderlich. Sie können auch die Funktion RANK () verwenden, um Top-N-Ergebnisse zu erhalten.
Verwenden Sie für die Leistung
NOT EXISTS
anstelle vonNOT IN
. Sehen Sie dies für mehr.quelle
FETCH NEXT N ROWS ONLY
Antwort unten.Wenn Sie Oracle 12c verwenden, verwenden Sie:
Weitere Informationen: http://docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfetch.html
quelle
In Bezug auf die schlechte Leistung gibt es eine Reihe von Dingen, die es sein könnte, und es sollte wirklich eine separate Frage sein. Es gibt jedoch eine offensichtliche Sache, die ein Problem sein könnte:
Wenn HISTORY_DATE wirklich eine Datumsspalte ist und einen Index hat, funktioniert dieses Umschreiben besser:
Dies liegt daran, dass eine Datentypkonvertierung die Verwendung eines B-Tree-Index deaktiviert.
quelle
Versuchen
quelle
Sie erhalten eine scheinbar zufällige Menge, da ROWNUM vor ORDER BY angewendet wird. Ihre Abfrage nimmt also die ersten zehn Zeilen und sortiert sie. 0 Um die zehn besten Gehälter auszuwählen, sollten Sie eine Analysefunktion in einer Unterabfrage verwenden und dann Folgendes filtern:
quelle