2011-05-25 106 views
1

我的一个朋友和我最近是有这个辩论,所以我不知道是否有人在这里实际上可能知道答案会发生什么。限制当Oracle子查询

通常,模拟的MySQL LIMIT start_index,result_count语法和MySQL和PostgreSQL的Oracle中LIMIT result_count OFFSET start_index功能,我们使用:

SELECT P.* FROM 
    (SELECT COL1...COLN, ROW_NUMBER() OVER ID_COLUMN AS RN FROM MY_TABLE) 
WHERE P.RN BETWEEN START_INDEX AND END_INDEX; 

相反的明确限制的功能,该替代装置需要被使用。 (如果还有更好的方法,请告诉我)

我们中的一个人认为这意味着Oracle实际上获取END_INDEX记录,然后只返回那些在START_INDEX上有rn的记录。这意味着当查找记录123,432-123,442时,Oracle将检索123,431条不必要的记录。然后有人认为,这意味着两个开放源码数据库(MySQL & PgSQL)的含义有一个简化它的方法。

相反的观点是,数据库管理系统的优化处理子查询,这意味着语法并不一定意味着行为。此外,LIMIT语法可能仅仅是语法糖,它们实际上是Oracle中必须明确说明的东西。

有没有谁能够确定这些是正确的解释?也许两者在某些方面是正确的?

回答

3

它是正确的,甲骨文过程 END_INDEX行和丢弃行1到START_INDEX-1,但它只提取行START_INDEX在光标END_INDEX。

我不知道LIMIT是如何在其他DBMS中实现的,但我无法想象他们如何做到这一点:他们如何知道他们在没有首先发现和丢弃的情况下获取结果集的第123,432行之前的123,431行?

在实践中,如果你发现自己施加一个LIMIT子句(或Oracle等同物)的比几百多START_INDEX,你真的需要重新考虑你的要求。

+0

不幸的是,背景是在自定义搜索语法分页。有时我们会寻找一位来自新泽西州的用户,但他们给了我们一封不好的电子邮件,一个与原始名字,姓氏首字母和状态无关的昵称。这个(在最后的初始和状态上搜索)在pas中返回了> 10k的结果(所以123k有点夸张)。看起来我们的选择要么是使用10k的开始索引。 – cwallenpoole 2011-05-25 11:28:29

+1

请注意,如果在“ID_COLUMN”上有索引,Oracle只能避免处理表中的所有行 - 例如,“ID_COLUMN”的最低值可能是检索到的最后一个记录。当然,列的名字强烈表明会有索引,但不能假设这:) – 2011-05-26 03:24:34