Oracle SELECT TOP 10 discos

Tengo un gran problema con una statement SQL en Oracle. Quiero seleccionar los 10 loggings principales orderados por STORAGE_DB que no están en una list de otra statement de selección.

Este funciona bien para todos los loggings:

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') 

Pero cuando estoy agregando

 AND ROWNUM <= 10 ORDER BY STORAGE_GB DESC 

Obtengo algún tipo de Registros "aleatorios". Creo que porque el límite toma lugar antes de la order.

¿Alguien tiene una buena solución? El otro problema: esta consulta es realmente lenta (10k + loggings)

Deberá colocar su consulta actual en una subconsulta de la siguiente manera:

 SELECT * FROM ( 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') ORDER BY STORAGE_GB DESC ) WHERE ROWNUM <= 10 

Oracle aplica rownum al resultado una vez que ha sido devuelto.
Debe filtrar el resultado después de que se haya devuelto, por lo que se requiere una subconsulta. También puede usar la function RANK () para get resultados Top-N.

Para el performance intente usar NOT EXISTS en lugar de NOT IN . Vea esto para más.

Con respecto a los malos resultados, hay muchas cosas que podrían ser, y realmente debería ser una pregunta aparte. Sin embargo, hay una cosa obvia que podría ser un problema:

 WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009') 

Si HISTORY_DATE realmente es una columna de date y si tiene un índice, esta reescritura tendrá un mejor performance:

 WHERE HISTORY_DATE = TO_DATE ('06.02.2009', 'DD.MM.YYYY') 

Esto se debe a que una conversión de tipo de datos deshabilita el uso de un índice B-Tree.

Si está utilizando Oracle 12c, puede usar:

search las siguientes N filas solamente

 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') ORDER BY STORAGE_GB DESC FETCH NEXT 10 ROWS ONLY 

Más información: http://docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfetch.html

Obtiene un set aparentemente aleatorio porque ROWNUM se aplica antes de ORDER BY. Por lo tanto, su consulta toma las primeras diez filas y las ordera.0 Para seleccionar los diez salarios principales, debe usar una function analítica en una subconsulta, luego filtrar eso:

  select * from (select empno, ename, sal, row_number() over(order by sal desc nulls last) rnm from emp) where rnm<=10 

intente SELECCIONAR * DESDE usuarios FETCH NEXT 10 ROWS ONLY;

Puedes simplemente usar TOP Clause

SELECCIONAR TOP 10 * FROM TABLE;

O

SELECCIONE column_name (s) FROM table_name WHERE ROWNUM <= number;