2012-09-17 118 views
4
SELECT * FROM ( 
    select * 
    from tableA 
    where ColumnA = 'randomText' 
    ORDER BY columnL ASC 
) WHERE ROWNUM <= 25 

在執行此查詢時,由於某些Oracle優化,查詢大約需要14分鐘才能執行。如果我刪除where子句,查詢將在幾秒鐘內執行。表中的大多數列都有索引,包括上面提到的索引。我在使用hibernate時對查詢的結構沒有太大的靈活性。hibernate oracle rownum問題

此查詢返回的結果瞬間也與正確的結果:

SELECT * 
FROM ( 
    select * 
    from tableA, 
     dual 
    where ColumnA = 'randomText' 
    ORDER BY columnL ASC 
) WHERE ROWNUM <= 25 

是有什麼我能做的,使用Hibernate?

更新:我使用EntityManager.createQuery(),我也使用setMaxResults(25)和setFirstResult()。上面的查詢是什麼hibernate的查詢看起來像,在觀察日誌

+0

請問您可以發佈HQL本身嗎?您的原始查詢是否包含集合的連接?此外,映射本身也很有用。 –

+0

你能否提供兩個查詢的解釋計劃? –

+0

@ctapobep http://pastebin.com/qjzu5HKc是HQL。正如你所看到的,沒有聯接。 – vritantjain

回答

-1

這意味着你正在使用hibernate/jpa?如果是這樣,我猜你正在使用EntityManager.createNativeQuery()來創建查詢?嘗試刪除您的位置限制,然後使用Query上的.setMaxResults(25)

無論如何,爲什麼你需要外部選擇?不會

select * 
from tableA 
where ColumnA = 'randomText' 
AND ROWNUM <= 25 
ORDER BY columnL ASC 

會產生預期的結果嗎?

+2

沒有外部選擇rownum不遵守訂單 –

+0

然後嘗試使用它沒有外部選擇和setMaxResults。如果這不起作用,我會非常驚訝。 – Korgen

+0

@Korgen我使用EntityManager.createQuery(),我也使用setMaxResults(25)和setFirstResult()。上面的查詢是hibernate查詢的樣子,通過觀察日誌。 – vritantjain

0

我沒有得到與您的查詢完全匹配的解釋計劃,但它似乎使用不同的索引爲這兩個查詢的oracle。

你能創建一個包含columnAcolumnL的索引嗎?

如果您的索引僅包含columnA,那麼您可以放棄該索引而不會對其他查詢的性能產生重大影響。

另一種方法是添加提示以使用快速查詢中使用的索引。但是這需要你使用原生的sql。

+0

查詢是動態構建的,因此columnL可能是表中的任何列。因此綜合指數不是一個可行的解決方案。 – vritantjain