快速从sqlserver中选择随机抽样

Byr*_*ock 15 sql database sql-server random performance

我有一个超过1000万行的巨大表.我需要从中有效地获取5000的随机抽样.我有一些行为者减少了我想要的总行数,如9毫米.

我尝试使用NEWID()的命令,但该查询将花费太长时间,因为它必须对所有行进行表扫描.

有更快的方法吗?

K. *_*ley 21

如果您可以使用伪随机采样并且您使用的是SQL Server 2005/2008,那么请查看TABLESAMPLE.例如,SQL Server 2008/AdventureWorks 2008中的一个示例基于行工作:

USE AdventureWorks2008; 
GO 


SELECT FirstName, LastName
FROM Person.Person 
TABLESAMPLE (100 ROWS)
WHERE EmailPromotion = 2;
Run Code Online (Sandbox Code Playgroud)

问题是TABLESAMPLE不是完全随机的,因为它从每个物理页面生成给定数量的行.你可能无法获得5000行,除非你也限制TOP.如果您使用的是SQL Server 2000,则必须生成与主键匹配的临时表,或者您必须使用NEWID()方法执行此操作.

  • 错误,tablesample通过选择适当数量的页面然后返回在这些页面上找到的所有行来工作.重点是避免碰到所有拿着桌子的页面. (2认同)

Joh*_*som 8

您是否考虑过使用TABLESAMPLE子句?

例如:

select *
from HumanResources.Department tablesample (5 percent)
Run Code Online (Sandbox Code Playgroud)


小智 6

SQL Server 2000解决方案,关于Microsoft(而不是较大的表上的慢NEWID()):

SELECT * FROM Table1
WHERE (ABS(CAST(
 (BINARY_CHECKSUM(*) *
  RAND()) as int)) % 100) < 10
Run Code Online (Sandbox Code Playgroud)

Microsoft的SQL Server团队意识到,无法轻松获取行的随机样本是SQL Server 2000中的常见问题.因此,该团队通过引入TABLESAMPLE子句解决了SQL Server 2005中的问题.此子句通过选择随机数据页并返回这些页上的所有行来选择行的子集.但是,对于我们这些仍然拥有在SQL Server 2000上运行且需要向后兼容性或需要真正行级随机性的产品的人来说,BINARY_CHECKSUM查询是一种非常有效的解决方法.

解释可以在这里找到:http: //msdn.microsoft.com/en-us/library/cc441928.aspx


fri*_*ism 5

是的,tablesample 是你的朋友(请注意,它在统计意义上不是随机的): msdn 上的 Tablesample