2009-11-24 182 views
25

我读过的很多SQL代码,似乎开发人员认为默认排序顺序始终成立。例如,在构建HTML选择列表时,他们只需要SELECT id, name FROM table而不会发出ORDER BY子句。处理默认排序顺序的SQL最佳实践

从我自己的经验看来,如果没有给出ORDER BY子句并且没有索引,dbms总是使用FIFO来命令数据。但是,订单不能保证。但是,如果没有对表格进行更改,我从来没有见过dbms重新排序数据。

如果表中没有更改,您是否曾经历过以非确定性顺序选择数据的dbms?

是否总是放置ORDER BY子句是最佳做法?

+6

,有定义,*没有默认的排序顺序*在兼容SQL的数据库。大多数数据库可以并且将以不同的顺序返回记录,这取决于查询的性质,甚至执行类似查询时索引的状态。假设订单很重要,您必须始终指定您想要数据的订单。未指定顺序的查询可能无法重复。 – 2009-11-24 21:53:19

回答

38

没有默认的排序顺序。即使表格有聚集索引,也不保证按照该顺序得到结果。如果您需要特定订单,则必须使用订单旁边的条款。

+0

你是第一个,毕竟 – 2009-11-24 21:52:22

+0

为第一。 – Yada 2009-11-25 00:18:18

9

如果您希望数据始终如一地出来,是的 - 您必须使用ORDER BY

6

是的。没有ORDER BY,没有“默认订单”,并且不能保证您将以FIFO/LIFO或任何其他订单取回数据。

至于开发商使用“SELECT ID,名称FROM表”,他们要么不称职或不关心订购任何产品出现英寸

3

没有严重的RDBMS保证任何顺序,除非你指定一个明确的ORDER BY。

其他任何只是纯粹的运气或anectodal - 如果你想要订单,你必须指定ORDER BY - 没有办法绕过。

1

也许您正在阅读的那些SQL查询的编写者并不关心返回的数据的顺序。最佳做法是在需要的地方使用它,以确保返回结果的顺序!

3

如果您想要订购数据,唯一保证任何事情的方法(包括我知道的每个主要RDBMS系统,绝对是Sql Server和Oracle)都包含ORDER BY子句。 FIFO与没有ORDER BY子句的情况下返回的订单数据完全无关,并且没有任何种类的DEFAULT排序顺序的概念。然而,所谓的DEFAULT排序顺序基本上是引擎获取数据,它可以基于索引,缓存数据,同时执行的查询,服务器上的负载等等的字面顺序。

This other stackoverflow thread基本上涵盖了与Sql Server相关的相同概念,AlexK blogged a repo来演示该行为。

3

即使像SELECT ... FROM table这样的简单查询也可以按各种顺序返回数据。我知道这在理论上是真实的,我知道这在实践中是真实的,并且当顺序在后续执行之间改变时(即使表中没有数据改变),我已经看到很多情况。

执行之间的顺序更改的一个典型示例是使用并行计划执行查询时。由于并行操作符在底层线程生成它时返回数据,因此结果中各行的顺序在每次运行之间都会有所不同。这种情况使得在你的例子中即使是简单的SELECT也会在每次运行时返回不同的结果。

15

正如其他海报中提到的,如果您没有指定排序顺序,那么SQL标准说结果可以按照查询处理器发现的最有利和最有效的顺序进行。

假设你为CUSTOMER表的所有行执行简单的无序SELECT操作,该表没有索引并且没有主键。查询处理器完成一次直接表扫描,并按照最初插入的顺序生成行(给出您看到的FIFO行为),这很可能,甚至可能。

如果您随后在STATE和CITY字段(按此顺序)上添加索引,然后查询WHERE STATE = 'NY',查询处理器可能会决定扫描STATE ='NY'的索引条目而不是做全表扫描。在这种情况下,它可能会实现STATE,CITY顺序中的行。

即使这是不确定的。例如,如果查询处理器收集的统计数据显示表中几乎所有的STATE值都是'NY'(可能是因为数据库是针对基于Albany的设备租赁业务),则可能会决定表扫描实际上更便宜比索引扫描,你会再次看到FIFO。

最好学习一些关于数据库如何计划查询的基础知识。您可以使用EXPLAIN语句来查看DBMS如何执行任何给定的查询,然后使用它来优化查询,在某些情况下按几个数量级。这是一个迷人而有用的学习领域。

3

在我与SQL的经验,大部分时间我不指定ORDER BY在SQL,因为该记录集显示在“客户端”网格型控制等地方动态排序是支持的 - 在这种情况下,通过SQL排序是不必要的,因为无论如何都会检查客户端。

这也做客户端,因为可能会使用相同的查询以不同的顺序在不同的地方显示数据。

因此,这是摆在一个ORDER BY只有最好的实践中,当

  • 数据的顺序是重要;和
  • 排序在数据库级别更高效。

即,如果前端显影剂将是“重新排序”也无妨,那么就没有点,因为它不太可能节省总的处理时间。

+0

这是一个很好的方面,有一个客户端将自行排序。当然,并不是所有查询都发送到客户端应用程序,有的正在创建导出文件,而ordierng可能非常重要。但是,是的,做最有效的做法是很好的,如果你打算在客户端重新排序,不排序可能是最有效的。但是,我会测试两种方式。 – HLGEM 2015-05-28 14:52:59

0

我正在写这个的情况下,如果有人想像我这样使用它。

嗯,我得到了令人满意的默认排序顺序,让我们说对于日志表,排序索引。例如,我通常对日志表(LIFO)的最后一行感兴趣,所以我使用DateTime DESC作为顺序。我也尝试过在主键旁边的其他字段(整数)上添加索引,并且它工作。

CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL, 
CONSTRAINT [PK_tableA] 
PRIMARY KEY CLUSTERED ([DateTime] DESC) 
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] 

或在SSMS中...

enter image description here