在视图中订购是否保证选择顺序?

时间:2011-09-02 11:36:32

标签: sql postgresql select

我认为使用某种顺序才有意义。我想要做的是在视图中包含ORDER BY子句,以便该视图上的所有SELECT都可以省略它。但是,我担心订购可能不一定会延续到SELECT,因为它没有指定订单。

是否存在视图指定的排序不会反映在该视图上的select结果中的情况(视图中的order by子句除外)?

3 个答案:

答案 0 :(得分:8)

您不能指望任何查询中没有明确ORDER BY子句的行的顺序。如果您查询有序视图,但未包含ORDER BY子句,如果它们的顺序正确,并且不希望它再次发生,请感到惊喜。

这是因为查询优化器可以根据查询,表统计信息,行计数,索引等以不同方式自由访问行。如果它知道您的查询没有ORDER BY子句,则可以按顺序忽略行顺序(咳嗽)以更快地返回行。

略偏离主题。 。

即使对于众所周知的排序规则,排序顺序在各个平台上也不一定相同。我知道在Mac OS X上排序UTF-8特别奇怪。 (PostgreSQL开发人员将其命名为 broken 。)PostgreSQL依赖于strcoll(),我理解它依赖于OS语言环境。

我不清楚PostgreSQL 9.1将如何处理这个问题。在9.1中,you can have multiple indexes, each with a different collation。未指定排序规则的ORDER BY通常会使用基础基表的列的排序规则,但优化程序将使用索引执行什么操作,该索引指定与基础中的未索引列不同的排序规则表

答案 1 :(得分:1)

无法看到如何进一步回复。在这里添加我的回复。

如果您手动编写查询,可以依赖于您可以依赖它的每种情况下的排序。

这是因为PostgreSQL会重写您在视图中合并的查询。

CREATE VIEW v AS SELECT * FROM people ORDER BY surname;
-- next two are identical
SELECT * FROM v WHERE forename='Fred';
SELECT * FROM people WHERE forename='Fred' ORDER BY surname;

但是,如果您将视图用作子查询,则排序可能不会保留,就像从不维护子查询的输出顺序一样。

所以 - 我说要依靠这个吗?不,可能更好地在应用程序中指定所需的排序顺序。无论如何,您还需要为每个其他查询执行此操作。如果它是DBA使用的实用程序视图,那么这是另一回事 - 我有很多实用程序视图提供排序输出。

答案 2 :(得分:-1)

虽然到目前为止观察结果仍然如此,但这个答案无论如何都不是决定性的。 @Catcall和我,两者都没有在文档中找到任何明确的内容,我不得不承认,我太懒了,无法理解源代码。

但为了观察,请考虑以下事项:

  1. SELECT * FROM (select * from foo order by bar) foobar;
    

    查询应返回 已订购

  2. SELECT * FROM vw_foo; -- where vw_foo is the sub-select above
    

    查询应返回 已订购

  3. SELECT * FROM vw_foo LEFT JOIN (select * from bar) bar ON vw_foo.id = bar.id;
    

    查询应使用它自行决定,并可能返回 无序

  4. 声明:

    就像@Catcall所说的那样,你永远不应该真正依赖任何隐式排序,因为很多时候它会留给数据库引擎。数据库旨在提高速度和可靠性;它们经常与内存接口,并尽可能快地拉/推数据。但是,订购不仅仅基于内存管理,还有几个因素。

    除非你有特定的东西,否则你应该在最后进行排序(在外部查询上)。


    如果上述观察结果为真,则以下内容应始终按正确顺序转换结果:

    SELECT * 
    FORM   (select   trunc(random()*999999+1) as i 
            from     generate_series(1,1000000) 
            order by i
           ) foo;
    

    简单的过程是:执行预处理并执行查询识别(识别订单存在),启动循环,获取第一个字段(生成随机数),按排序顺序添加到输出堆栈。排序也可以在堆栈生成结束时发生,而不是在期间(例如,编译列表然后进行排序)。这取决于版本控制和查询。