SQL Large Table选择随机行策略

Las*_*ker 8 sql-server select

我想从一个非常大的表(10密耳记录)中选择一个随机行.因此,最常见的策略,例如RAND()并且NEWID()似乎并不实用.

我尝试了以下策略,并想知道这是否是最理想的方式.

  1. 创建一个名为"RandomSort"的新字段作为UniqueIdentified

  2. 在每个小时/每天结束时,将对Update RandomSort = NewID()整个表格进行操作

  3. 每次我需要查询,我都可以做 Top 10 Order by RandomSort

它确实完成了工作(优于ORDER BY NewID),但不确定这是否是目前为止的最佳实践?

Mit*_*eat 3

添加一个标识列“rowid”(intbigint取决于您的表大小)并在其上创建唯一的非聚集索引。

以下查询使用该NEWID()函数返回表中大约百分之一的行:

SELECT * FROM MyTable
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), rowID) & 0x7fffffff AS float) / CAST (0x7fffffff AS int)
Run Code Online (Sandbox Code Playgroud)

rowId 列包含在 CHECKSUM 表达式中,以便 NEWID() 每行计算一次,以实现按行采样。该表达式的CAST(CHECKSUM(NEWID(), rowid) & 0x7fffffff AS float / CAST(0x7fffffff AS int)计算结果为 0 到 1 之间的随机浮点值。

事实上,您可以使用表中的任何列索引列(我相信)。

如果您只想选择一个随机行:

SELECT TOP 1 * FROM table 
WHERE rowid >= RAND(CHECKSUM(NEWID())) * (SELECT MAX(rowid) FROM table) 
Run Code Online (Sandbox Code Playgroud)

如果该rowid列已建立索引,则此操作会在恒定时间内起作用。注意:这假设rowid均匀分布在范围 中0..MAX(rowid),因此建议添加标识列。如果您的数据集具有其他分布,您的结果将会出现偏差(即某些行将比其他行更频繁地被选取)。