在内联视图中设置时Oracle是否保证最终输出行顺序

T.S*_*.S. 0 oracle order-by

此查询基于 2 个表,其中某些行PerfData1具有多个子记录。行不重复,但有些id行重复。我只需要获取其中的 1 行,这也是一个分页查询,它需要获取总数或现有项目以及最终子集。

查询工作正常。但是,我不确定在内联视图(内部ORDER BY)中设置的顺序是否会保留在最终输出中。到目前为止,没有看到任何偏差。但我记得在 SQL Server 世界中这是不能保证的,因此我需要 2 个ORDER BY子句。

    SELECT 
        All_Results_Table.*
    FROM
    (
        SELECT 
            Rownum_Table.*,
            COUNT(*) OVER() as sys___countAllFoundRecords,
            ROWNUM sys___outputRownum
        FROM 
        (
            SELECT 
                ROW_NUMBER() OVER(PARTITION BY PerfData1.id ORDER BY PerfData1.id) AS sys___multivalueRowSequence, -- This is OPTIONAL when we DON'T want dupe IDs
                ROW_NUMBER() OVER(order by 1) AS sys___innerRowNumber,
                PerfData1.id,
                PerfData1.c1 item,
                PerfData2.c1 subitem
            FROM 
                PerfData1 inner join 
                PerfData2 on PerfData1.id = PerfData2.fkId
            WHERE (1 = 1) 
            ORDER BY id, subitem desc --<<-- WILL THIS ORDER STAY in the FINAL OUTPUT 
        ) Rownum_Table
        WHERE sys___multivalueRowSequence = 1 -- This is OPTIONAL when we DON'T want dupe IDs
    ) All_Results_Table
    WHERE 
        sys___outputRownum BETWEEN 200 AND 230
Run Code Online (Sandbox Code Playgroud)

上述 SQL中设置的顺序会ORDER BY保留在最终输出中吗?

Dav*_*ett 5

对于任何 SQL 实现,根本无法保证最终输出的顺序,除非您明确声明您想要的顺序。

\n

在某些情况下,另一个特定的可能性可能很大,但不能保证。SQL 是一种声明性语言,任何您不声明的内容,数据库都可以在将来的运行中自由地不会重新定位。现在,您可能会在每个可以想象的测试中得到相同的顺序,但稍后当数据增长和/更改平衡时,或者有人更改受影响表的索引选择,或者一个或多个表变成视图,或者数据库升级到较新的版本具有大量推文查询规划器,数据的处理方式可能会发生重大变化,并且顺序会丢失。

\n

如果您想保证复杂查询或简单查询的最后一层的特定顺序,则需要ORDER BY在该级别使用子句显式声明您想要该顺序。

\n
\n

长话短说:博士:不。

\n
\n

来自评论:

\n
\n

在这种情况下,我可以使用一些提示来告诉 ORACLE 保留原始顺序吗?因为你知道,在这些多层查询中,我相信,Order by 会消耗性能

\n
\n

ORDER BY几乎总是\xc2\xb9有一些性能成本,但如果您需要按该顺序的数据,那么您需要按该顺序\xc2\xb2,因此需要付出代价。正如保罗所说,价格可能几乎为零:如果由于查询规划器决定的方式需要按此顺序排序数据是获取您所要求的内容的最佳方法,则无需重新排序,唯一的成本是规划者注意到这个\xc2\xb3 所需的几分之一秒。

\n

要对输出进行排序,ORDER BY必须应用于查询的最外层部分,在本例中ORDER BY id, subitem desc移至最终WHERE子句之后。没有其他方法可以保证最终的顺序,任何其他似乎有效的方法都依赖于可能随时更改的未定义行为。

\n

此外:关于ORDER BY在子查询中使用这样的;查询规划器可能完全忽略它。有些数据库实际上会认为它的存在是语法错误。如果您依赖它对 的输出进行特定排序,ROW_NUMBER() OVER(order by 1)那么我会改用ROW_NUMBER() OVER(order by id, subitem desc).

\n

[1] 在这种情况下,它不包括可以查找/扫描索引的简单查询,并且不引用任何不属于该索引coveredincluded通过该索引引用的内容,但如果您假设请求特定的排序总是要付出代价,那么您永远不会错导致不愉快的意外的方式

\n

[2] 尽管有时让数据库以任何旧顺序丢弃数据并在调用应用程序中进行排序是有益的,但将排序负载从数据库中移开,因为应用程序层通常最容易扩展

\n

[3] 或者它可能有两个计划选项,它们在其他方面看起来表现相同,但其中一个会自然地根据您想要的内容进行排序,而无需额外的工作,因此它会选择该计划而不是另一个。

\n