2012-09-17 76 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