Eu tenho um grande problema com uma instrução SQL no Oracle. Desejo selecionar os 10 melhores registros ordenados por STORAGE_DB que não estão em uma lista de outra instrução de seleção.
Este funciona bem para todos os registros:
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')
Mas quando estou adicionando
AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC
Estou recebendo algum tipo de registro "aleatório". Eu acho que porque o limite ocorre antes do pedido.
Alguém tem uma boa solução? O outro problema: Esta consulta é muito lenta (10k + registros)
Respostas:
Você precisará colocar sua consulta atual na subconsulta como abaixo:
O Oracle aplica o rownum ao resultado após o retorno.
Você precisa filtrar o resultado após o retorno, para que seja necessária uma subconsulta. Você também pode usar a função RANK () para obter os melhores resultados.
Para obter desempenho, tente usar
NOT EXISTS
no lugar deNOT IN
. Veja isso para mais.fonte
FETCH NEXT N ROWS ONLY
resposta abaixo.Se você estiver usando o Oracle 12c, use:
Mais informações: http://docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfetch.html
fonte
No que diz respeito ao fraco desempenho, pode haver várias coisas, e realmente deve ser uma pergunta separada. No entanto, há uma coisa óbvia que pode ser um problema:
Se HISTORY_DATE realmente for uma coluna de data e se tiver um índice, essa reescrita terá um desempenho melhor:
Isso ocorre porque uma conversão de tipo de dados desabilita o uso de um índice B-Tree.
fonte
experimentar
fonte
Você obtém um conjunto aparentemente aleatório porque ROWNUM é aplicado antes do ORDER BY. Portanto, sua consulta pega as dez primeiras linhas e as classifica.0 Para selecionar os dez principais salários, você deve usar uma função analítica em uma subconsulta e filtrar isso:
fonte