当前位置: 首页 > 面试题库 >

如何在Oracle中加快row_number的速度?

王宏深
2023-03-14
问题内容

我有一个看起来像这样的SQL查询:

SELECT * FROM(
    SELECT
        ...,
        row_number() OVER(ORDER BY ID) rn
    FROM
        ...
) WHERE rn between :start and :end

从本质上讲,正是ORDER BY部件在减慢速度。如果我要删除它,则EXPLAIN成本会下降一个数量级(超过1000倍)。我已经试过了:

SELECT 
    ...
FROM
    ...
WHERE
    rownum between :start and :end

但这并不能给出正确的结果。有什么简单的方法可以加快速度吗?还是我需要花更多时间使用EXPLAIN工具?


问题答案:

ROW_NUMBER的效率很低Oracle

有关性能的详细信息,请参见我的博客中的文章:

  • 甲骨文:ROW_NUMBER与ROWNUM

对于您的特定查询,建议您将其替换为ROWNUM并确保使用索引:

SELECT  *
FROM    (
        SELECT  /*+ INDEX_ASC(t index_on_column) NOPARALLEL_INDEX(t index_on_column) */
                t.*, ROWNUM AS rn
        FROM    table t
        ORDER BY
                column
        )
WHERE rn >= :start
      AND rownum <= :end - :start + 1

该查询将使用 COUNT STOPKEY

另外,请确保您column不可为空,或添加WHERE column IS NOT NULL条件。

否则,索引不能用于检索所有值。

请注意,ROWNUM BETWEEN :start and :end没有子查询就无法使用。

ROWNUM总是最后被分配并最后检查,这就是方法ROWNUM总是无间隙地排列。

如果您使用ROWNUM BETWEEN 10 and 20,则满足所有其他条件的第一行将成为返回的候选项,并被临时分配ROWNUM = 1并通过的测试失败ROWNUM BETWEEN 10 AND 20

然后,下一行将是候选行,并分配有ROWNUM = 1和失败等,因此,最后,将根本不返回任何行。

应该通过将ROWNUM放入子查询中来解决此问题。



 类似资料:
  • 问题内容: 在PostgreSQL 8.4中,我想从3个ID为ID的表中创建一个视图。因此,我想采用以下结构: 我可以选择,并从表: 如何在视图中创建列? 更新 我找到了解决方案: 但我不知道如何在中使用它。我怎么把它放在那里? 问题答案: 您不能使用删除或添加列。我引用ALTER VIEW上的手册 : 更改视图的各种辅助属性。(如果要修改视图的定义查询,请使用。) 但是一个简单的方法并不能解决问

  • 我已经在我的机器上安装了Oracle 11g XE。现在我通过系统模式连接它。如何创建自己的数据库。就像在MS SQL中使用 如何在Oracle11gXe中创建这样的数据库。

  • 问题内容: 我们开始在我们的项目中大量使用GWT,并且GWT编译器的性能变得越来越令人讨厌。 我们将开始改变工作方式以减轻该问题,包括更加强调托管模式浏览器,这推迟了以后运行GWT编译器的需求,但这带来了自身的风险,特别是在直到比我们想要的晚得多的时候,才能够真正使用浏览器解决问题。 理想情况下,我们希望使GWT编译器本身更快-一分钟的编译相当小的应用程序花费了很多精力。但是,如果使用的是相当幼稚

  • 当Google发布新的时,我一直在等待,因为我在

  • 图片是放在金蝶服务器上,前端页面el-image的src放图片的访问路径,加载的速度得4 5秒吧,请问大神这种情况怎么优化,使图片的加载速度变快?

  • 问题内容: 有没有像MySQL中的任何功能和像甲骨文和其他DBMS提供的? 我想在查询中生成一个ID,但是在MySQL中这些功能不存在。还有其他选择吗? 问题答案: Mysql没有它们,但是您可以使用使用用户定义的变量的以下表达式进行模拟: 像这样: 但是如果您要重用该会话,它将仍然被设置,因此您需要像这样重置它: 参见SQLFiddle。 可能,但是火车残骸;我建议在应用程序层处理该要求。