Oracle SELECT TOP 10 záznamov

Mám veľký problém s príkazom SQL v Oracle. Chcem vybrať TOP 10 záznamov zoradených podľa STORAGE_DB, ktoré nie sú v zozname z iného príkazu select.

Tento funguje dobre pre všetky záznamy:

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

Ale keď pridávam

AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC

Dostávam nejaké "náhodné" Záznamy. Myslím si, že preto, lebo limit sa zavedie pred objednávkou.

Má niekto dobré riešenie? Ďalší problém: Tento dotaz je naozaj pomalý (10k+ záznamov)

Riešenie

Budete musieť dať svoj aktuálny dotaz do poddotazu, ako je uvedené nižšie:


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 
Komentáre (4)

Pokiaľ ide o slabý výkon, môže to byť spôsobené mnohými vecami a malo by to byť naozaj samostatnou otázkou. Existuje však jedna zjavná vec, ktorá by mohla byť problémom:

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

Ak je HISTORY_DATE skutočne stĺpec s dátumom a ak má index, potom bude tento prepis výkonnejší:

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

Je to preto, že konverzia dátového typu znemožňuje použitie indexu B-Tree.

Komentáre (0)

Získate zrejme náhodnú množinu, pretože ROWNUM sa použije pred ORDER BY. Váš dotaz teda vyberie prvých desať riadkov a zoradí ich.0 Ak chcete vybrať desať najvyšších platov, mali by ste použiť analytickú funkciu v poddotazu a tú potom filtrovať:


 select * from 
     (select empno,
             ename,
             sal,
             row_number() over(order by sal desc nulls last) rnm
    from emp) 
 where rnm
Komentáre (0)