为什么ORDER BY不属于View?


51

了解 无法拥有 ORDER BY视野。(至少在我正在使用的SQL Server 2012中)

我也理解排序视图的“正确”方法是通过在查询视图ORDER BYSELECT语句周围放一个。

但是,对于实际的SQL和视图的用法而言,它相对较新,所以我想了解为什么这是设计使然。如果我正确地遵循了历史记录,这曾经是可能的,并且已从SQL Server 2008中明确删除,依此类推(请不要在确切的版本上引用我的意思)。

但是,我想出Microsoft为什么删除此功能的最佳理由是因为“视图是未排序的数据集合”。

我假设有一个很好的,合理的理由来说明为什么View应该不排序。为什么视图不能只是扁平化的数据收集?为什么特别排序?似乎很难(至少对我/恕我直言)提出一种具有排序视图的情况。


2
第一个答案是完美的。我建议您是否要订购视图,为什么不这样做。从[YourView]中选择[列],然后按[列]排序
Zane

简短答案:“出于同样的原因,ORDER BY不属于表。”
ypercubeᵀᴹ

Answers:


38

(当然,不包括索引视图。)

没有实现视图-不存储数据,那么如何排序呢?视图有点像一个存储过程,只包含一个SELECT不带参数的视图……它不保存数据,它只保存查询的定义。由于对视图的不同引用可能需要以不同的方式对数据进行排序,因此您执行此操作的方式(就像从表中进行选择一样,根据定义,该表也是行的未排序集合)将在外部查询中包含排序依据。

还可以对历史有所了解。你可能从来没有ORDER BY在视图中,也没有包括TOP。并且在这种情况下,ORDER BY指示由包括哪些行TOP,而不是如何显示它们。正巧在SQL Server 2000中,如果TOP100 PERCENT{some number >= number of rows in the table},优化是相当简单的,它结束了生产带有几分匹配的计划TOP/ORDER BY。但是,这种行为从未得到保证或记录,只是根据观察来依靠的,这是一个坏习惯。当SQL Server 2005发布时,由于优化程序的更改(导致使用不同的计划和运算符),该行为开始“中断”。TOP / ORDER BY如果是的话将被完全忽略TOP 100 PERCENT。一些客户对此抱怨很大,以至于Microsoft发出了一个跟踪标志以恢复旧的行为。我不会告诉您该标志是什么,因为我不希望您使用它,并且我想确保该意图是正确的-如果您想要可预测的排序顺序,请ORDER BY在外部查询上使用。

总结并尽力澄清您的观点: Microsoft没有删除任何内容。他们使产品变得更好,并且作为副作用,这种无证,无保证的行为变得不那么可靠。总体而言,我认为该产品更好。


这里提到(在注释中),TOP它对结果集执行游标操作。因此,它可以具有明确的顺序。
蒂姆·施密特

@TimSchmelter在优化器看到TOP 100 PERCENT / ORDER BY并从计划中完全删除它时无济于事。试试看。
亚伦·伯特兰

这只是一个旁注。无论如何,其余的注释如下:“计划在SQL Server的未来版本中弃用SELECT TOP x技巧,因此最好不要使用它。”
蒂姆·施密特

@TimSchmelter,这已经是个禁忌。我认为它不会很快停止在任何新版本中工作,因为它将破坏太多现有代码。
亚伦·伯特兰

2
@TimSchmelter那里的顺序不是在谈论行的顺序,而是在谈论行中列的顺序。在SQL Server中,我们通常不谈论行是元组,因为行的物理实现对我们是如此明显(表以您定义它们的顺序列出了这些列)。
亚伦·伯特兰

9

如果允许对视图进行排序,那么结果的顺序应该是什么?

CREATE VIEW dbo.V1
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number ASC

GO

CREATE VIEW dbo.V2
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number DESC

GO

SELECT *
FROM   dbo.V1
       JOIN dbo.V2
         ON V1.number = V2.number 

我不明白这一点。除了编写数据库视图外,您还可以编写普通的sql查询。那么在那种情况下结果的顺序应该是什么?谢谢
hqt 16/12/19

7

一种可能是避免发生冲突的排序-如果视图按一个顺序排序,而该视图上的选择按另一个顺序排序(不知道视图的排序),则可能会导致性能下降。因此,将分类要求留给用户更为安全。

另一个原因是,排序会带来性能成本,因此,当只有一些用户需要排序时,为什么要惩罚视图的所有用户。


5

ANSI SQL仅允许ORDER BY出于最多种原因对最外部的查询进行操作,其中一个原因是将子选择/视图/ CTE连接到另一个表并且外部查询具有ORDER BY自身时发生的情况。

SQL Server从不在视图内部支持它(除非您使用它来欺骗它TOP 100 PERCENT,在我看来它主要是触发错误)。

即使触发了该错误,结果也从未变得可靠,而且排序也并非始终如您所愿。

有关完整的技术说明,请参阅Query Optimizer团队的博客文章,以将TOP 100%ORDER BY视为有害。

此代码的默认计划实现恰好是在执行TOP操作时对行进行排序。通常,这意味着结果碰巧是按排序顺序返回的,这使客户认为可以保证对行进行排序。实际上并非如此。如果希望按排序顺序将行返回给用户,则需要在最外面的查询块上使用ORDER BY(根据ANSI)以保证输出显示顺序。


3

视图的行为类似于表,其内容由查询结果确定。

桌子没有顺序;他们只是成排的袋子。

因此,视图也没有顺序。不过,您可以通过选择特定ORDER中的行对它们进行排序。


1
表...只是行袋 -然后viwes只是虚拟的包包虚拟行-视图“不存在” -如没有保存这些数据的话-他们只是在“存储查询的定义,基本上”。
marc_s 2012年

1
+1对我而言,表格和视图的等效性似乎是视图不应该包含“排序依据”的
主要原因

1
“视图的行为类似于表”。我会说“视图的行为类似于基表。视图是表。”
ypercubeᵀᴹ

-2

尚未给出的一个答案是“ order by”可能会干扰谓词推送,这可能会极大地影响性能。

一个示例是一个视图,该视图将大量数据汇总为前10位/有序的10行摘要:

select * from TopOrderedView; -- Ordered 10 line summary in 5s

对于具有强谓词的相同情况:

select * from TopOrderedView where <condition>; -- Ordered 2 line summary in still 5s

由于top / order by阻止谓词在管道中的较早运行,因此仍然需要花费相同的时间。这可能会导致不必要的行得到处理,并且该计划将类似于没有谓词的行。

开发人员是否应该在下达订单之前进行推送实际上是开发人员的选择,可以更改答案。通常,推动是合乎逻辑的意图。

逻辑上使用“前100%”可允许谓词推送,但是不幸的是,在这种情况下,实现忽略了“ order by”,从而破坏了意图。

对于实际用例,一个不错的折衷方案是使引擎执行“拉动排序”。 这将允许在视图中指定“排序依据”(排名前100%或不排名最高),并且仅当视图是直接选择而无显式排序依据,无联接,无集合,无时才使用该顺序视图链接等。此简单模型可以支持上面列出的两种情况。


-6

您可以创建一个具有排序依据的视图,并在查询后保留该排序依据:

从.....选择顶部99.999999999999%*


1
为什么不只是SELECT TOP 100 PERCENT ...呢?
Max Vernon

2
@Max可能与此技巧类似-并不是一个好主意。
亚伦·伯特兰

同意,@ AaronBertrand-仅注意无需使用99.99999999999 :-)
Max Vernon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.