【问题标题】:What happens when limiting an oracle subquery限制 oracle 子查询时会发生什么
【发布时间】:2011-05-25 09:20:54
【问题描述】:

我和我的一个朋友最近就这个问题进行了辩论,所以我想知道这里是否有人真的知道答案。

通常,为了在 Oracle 中模拟 MySQL 的 LIMIT start_index,result_count 语法和 MySQL 和 PostgreSQL 的 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 记录,然后只返回那些 rn 超过 START_INDEX 的记录。这意味着在查找记录 123,432-123,442 时,Oracle 将检索 123,431 条不必要的记录。然后有人争辩说,暗示提到的两个开源数据库(MySQL 和 PgSQL)有一种捷径。

反驳的论点是 DBMS 已针对处理子查询进行了优化,这意味着语法不一定暗示行为。此外,LIMIT 语法很可能只是语法糖,它们实际上是对必须在 Oracle 中明确说明的内容的包装。

有没有人可以确定哪些是正确的解释?也许两者在某些方面都是正确的?

【问题讨论】:

    标签: mysql oracle postgresql


    【解决方案1】:

    Oracle处理END_INDEX行并丢弃第1行到START_INDEX-1行是正确的,但它只获取游标中的START_INDEX行到END_INDEX行。

    我不知道 LIMIT 是如何在其他 DBMS 中实现的,但我无法想象他们会怎么做:他们怎么知道他们正在获取结果集的第 123,432 行而不首先找到并丢弃之前的 123,431 行?

    在实践中,如果您发现自己应用了 START_INDEX 超过数百个的 LIMIT 子句(或 Oracle 等效子句),那么您确实需要重新考虑您的要求。

    【讨论】:

    • 不幸的是,上下文是自定义搜索语法中的分页。有时我们会寻找来自 NJ 的用户,但他们给了我们一封错误的电子邮件,一个与原始名字、姓氏首字母和州无关的昵称。这(对最后一个初始值和状态的搜索)在过去返回了 >10k 的结果(所以 123k 有点夸张)。看起来我们的选项要么使用 10k 中的起始索引。
    • 请注意,如果ID_COLUMN 上有索引,Oracle 只能避免处理表中的所有行——例如,ID_COLUMN 的最小值可能是检索到的最后一条记录。当然,列名强烈暗示会有索引,但不能假设这样:)
    猜你喜欢
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    相关资源
    最近更新 更多