Oracle SELECT TOP 10 kayıtları

Oracle'da bir SQL Deyimi ile ilgili büyük bir sorunum var. Başka bir select deyiminden bir listede olmayan STORAGE_DB tarafından sıralanan TOP 10 Kaydı seçmek istiyorum.

Bu, tüm kayıtlar için iyi çalışır:

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

Ama eklediğimde

AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC

Bir tür "rastgele" Kayıt alıyorum. Sanırım limit siparişten önce gerçekleştiği için.

İyi bir çözümü olan var mı? Diğer sorun: Bu sorgu gerçekten çok yavaş (10k+ kayıt)

Çözüm

Mevcut sorgunuzu aşağıdaki gibi alt sorguya koymanız gerekir:


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 
Yorumlar (4)

Düşük performansla ilgili olarak, bunun pek çok nedeni olabilir ve bu gerçekten ayrı bir soru olmalıdır. Ancak, sorun olabilecek bariz bir şey var:

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

HISTORY_DATE gerçekten bir tarih sütunuysa ve bir dizine sahipse, bu yeniden yazma daha iyi performans gösterecektir:

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

Bunun nedeni, bir veri türü dönüşümünün B-Ağacı dizininin kullanımını devre dışı bırakmasıdır.

Yorumlar (0)

ORDER BY'den önce ROWNUM uygulandığı için görünüşte rastgele bir küme elde edersiniz. Yani sorgunuz ilk on satırı alır ve bunları sıralar.0 İlk on maaşı seçmek için bir alt sorguda analitik bir işlev kullanmalı, ardından bunu filtrelemelisiniz:


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