Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
微软SQL Server(MSSQL)和#x27;订购人';将值保持在一起,但不指定顺序(按偏序排列)_Sql_Sql Server 2008 R2_Sql Order By - Fatal编程技术网

微软SQL Server(MSSQL)和#x27;订购人';将值保持在一起,但不指定顺序(按偏序排列)

微软SQL Server(MSSQL)和#x27;订购人';将值保持在一起,但不指定顺序(按偏序排列),sql,sql-server-2008-r2,sql-order-by,Sql,Sql Server 2008 R2,Sql Order By,我使用的是MSSQL 2008 R2,但这是一个一般的SQL问题。我想对结果进行排序,只是为了使相同的值彼此相邻,而不指定确切的排序顺序 比如说 create table t (a int not null, b int not null) insert into t values (1, 1), (1, 2), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2) select * from t order by a 这将具有我想要的属性,即a=1的所有行首先显示

我使用的是MSSQL 2008 R2,但这是一个一般的SQL问题。我想对结果进行排序,只是为了使相同的值彼此相邻,而不指定确切的排序顺序

比如说

create table t (a int not null, b int not null)

insert into t values (1, 1), (1, 2), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2)

select *
from t
order by a
这将具有我想要的属性,即a=1的所有行首先显示,然后是a=2,然后是a=3。 我同样可以指定'order b a desc',并首先得到a=3行

但事实上,我会很高兴得到所有的a=2行,然后是a=1,然后是a=3

所以我上面的查询是过度指定的;它要求服务器提供一个特定的排序顺序,而我实际上并不需要该顺序;我只想将相同的值分组在一起。对于一个大表,如果服务器能够更灵活地选择返回行的顺序,并且需要将相同的值放在一起,那么服务器可能能够更高效地查询

是否有一些SQL构造,例如

   select *
   from t
   order by a indeterminate

如果我可以指定“只要相等的元素保持在一起,您可以任意排序”?

我认为没有您所描述的内容,字段上的聚集索引通常会按照索引值的顺序返回行,而没有order by,但这不能保证

但是,如果您有该索引,那么按a排序的
成本将是微不足道的


当然,如果你想随机化顺序,你可以这样做,但你似乎希望有一个更好的选择,任何这样做的方法都不会有更好的效果。

我不认为有任何东西像你描述的那样,字段上的聚集索引通常会按索引值的顺序返回行,而不返回order by,但这不能保证

但是,如果您有该索引,那么按a
排序的
成本将是微不足道的


当然,如果你想随机排列顺序,你可以这样做,但你似乎希望有一个更好的选择,任何这样做的方法都不会有更好的效果。

我认为这是一个有趣的问题。您正在寻找集群,但并不真正关心集群是否有序。简单的回答是不,没有这样的事情

的确,对集群进行排序是过度指定了您的需求,但是对于规模不太大的问题,这是指定答案的最有效方法。让我们考虑一下SQL Server将如何满足您的请求

让我们假设在第一个场景中,您的数据处于无序堆中,即没有聚集索引,并且您很少执行此请求。为了满足您的请求,SQL Server可以立即返回第一行,因为您不关心订单。但是,在从第二个集群返回任何内容之前,它必须获取整个结果集,以了解最后一行是否属于第一个集群。因此,在从磁盘读取所有内容之前,您几乎无法获得很多结果

到目前为止,第一个场景非常简单,但是让我们考虑一下SQLServer可能如何跟踪这些集群。假设您有属于

m
集群的
n
行数据。当SQL Server遍历您的结果时,它可以立即返回属于第一个集群的结果。但是,对于其他
m-1
集群,它需要将它们存储在某个地方

SQL Server将索引保存在树中,所以让我们先考虑一下。对于

m-1
集群,树需要
O(log(m))
deep。因此,查找任何特定行所属的集群的运行时间是
O(log(m))
。此查询的总运行时间为
O(nx log(m))

SQL Server能做得更好吗?它可以通过将这些索引保存在散列中来实现。在has中查找行簇的时间是
O(1)
。因此,总运行时间为
O(n)
。这里的权衡是散列需要时间,好的散列函数很难确定,而且散列需要保留比实际需要更多的空间才能获得好的性能。因此,对于较小的问题规模,树更快、更有效

所以在第一个场景中,我们能做的最好的事情就是
O(n)
,使用一个小但有效的常数

让我们考虑第二个场景,在这个月中,你想不止一次地做这个查询。你需要一个索引。索引保留集群中的所有行,所有集群的顺序是每次插入

O(m)
。你得到了什么回报?您的查询只需要从顶部(或底部)遍历索引,返回它看到的每一行。这将给您一个有序的结果。查询中不需要任何工作。我们在insert(以及update和delete)上完成了所有的操作

所有这些都假设您的表被安排在一个磁盘上,其中访问此数据的最有效方式是从一端到另一端遍历数据。当您将数据跨磁盘分区时,情况就不再是这样了。虽然我认为您应该将数据保存在内存中,但您不可能总是负担得起那么多的内存,因此可能会出现分区问题

对于分区的情况,我强烈建议使用RAID解决方案,这样您的所有查询都会受益,而不仅仅是这一个。通过以较小的规模进行条带化,无论数据是如何分布的,都可以获得性能。除非您碰巧获取了只属于一个磁盘的数据,否则您就没事了


如果在非RAID设备上进行分区,RAID将无法正常工作,那么也许您可以考虑将多个查询拼接在一起,每个查询都跨越一个分区。p> 我认为这是一个有趣的问题。您正在寻找集群,但并不真正关心集群是否有序。简单的回答是不,没有这样的事情

的确,对集群进行排序是过度指定了您需要的内容