我想从一张非常大的桌子(10密耳的记录)中选择一个随机行。因此,RAND()
和NEWID()
等最常见的策略似乎并不实际。
我尝试过以下策略,想知道这是否是最理想的方法。
创建名为'RandomSort'的新字段为UniqueIdentified
在每个小时/每天结束时,我会对整个表格进行Update RandomSort = NewID()
Top 10 Order by RandomSort
它确实完成了工作(优于ORDER BY NewID
),但不确定这是否是目前为止的最佳做法?
答案 0 :(得分:3)
添加标识列' rowid' (int
或bigint
取决于您的表格大小)并在其上创建唯一的非聚集索引。
以下查询使用NEWID()
函数返回表的大约1%的行:
SELECT * FROM MyTable
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), rowID) & 0x7fffffff AS float) / CAST (0x7fffffff AS int)
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)
如果rowid
列已编制索引,则此操作会在固定时间内生效。注意:这假设rowid
均匀分布在0..MAX(rowid)
范围内,因此建议的标识列添加。如果您的数据集具有其他分布,则结果将会偏斜(即,某些行的选择频率会高于其他行)。