2011-08-16 49 views
5

,当我搜索在网络上的Oracle分页查询,其中大部分叫我换两次查询:区别使用ROWNUM

SELECT * 
    FROM (SELECT t.*, ROWNUM rn 
      FROM tableName t 
     WHERE ROWNUM < 200) 
WHERE rn > 100 

只是想知道如果我能为键入:

SELECT *, ROWNUM rn 
    FROM tableName t 
WHERE ROWNUN BETWEEN 100 AND 200 

看起来第二个也适用。这两个查询之间是否存在性能差异?

+1

我想你可能已经得到了你需要的答案,但是我发现新来的Oracle经常会遇到分页查询的困扰,特别是因为mysql使得LIMIT关键词变得如此简单。我会说这是Oracle初学者做错的最常见的事情之一,所以我最近写了一篇关于它的文章 - http://betteratoracle.com/posts/18-limiting-query-results-top-n-and-窗口查询 –

回答

4

问题是您正在生成与ROWNUM相同的查询过滤。因此,你必须有一个子查询的原因是先生成rownum然后应用过滤。为什么BETWEEN可以正常工作,可能是引擎处理查询的一些细微差别,但我会保持警惕,它可能不会始终如一地给您提供正确的结果。所以这不是一个表现问题,因为这是一个真正获得正确结果的问题。

本文解释了为什么你必须把比子查询外的更大。 http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/pseudocolumns009.htm

SELECT * FROM employees 
    WHERE ROWNUM > 1; 

“的第一行中读取被指定为1 ROWNUM,使条件为假的第二行是现在是第一行,并且分配了1的ROWNUM并使条件成为假,随后所有行都无法满足条件,因此不会返回行。“

4

使用ROWNUM正确的方法是:

SELECT x.* 
    FROM (SELECT t.*, 
       ROWNUM rn 
      FROM tableName t) AS x 
WHERE x.rn > 100 
    AND x.rn < 200 

BETWEEN是包含的,所以这两个查询是不相同的逻辑。

有关ROWNUM的更多信息,请参见this link (includes link to Oracle documentation

+0

感谢您的回答。我主要关心的是在我的问题中,这两个查询之间有什么表现差异。你可以看看下面的链接:http://stackoverflow.com/questions/241622/paging-with-oracle 它包装查询两次。 – GaryX

+0

@GaryX:正如我所说的,所提供的查询不完全相同;第二个查询将返回表中的所有内容。在获得有效数据之前,性能是一个关注点。 –

+0

@OMG小马,你的意思是说,“除非你得到有效的数据,性能不值得关注”? –