我想从一个非常大的表(10密耳记录)中选择一个随机行.因此,最常见的策略如RAND()和NEWID()似乎并不实用.
我尝试了以下策略,并想知道这是否是最理想的方式.
>创建一个名为’RandomSort’的新字段作为UniqueIdentified
>在每小时/每天结束时,将对整个表执行Update RandomSort = NewID()
>每次我需要查询时,我都可以通过RandomSort进行前10个订单
它确实完成了工作(优于ORID BY NewID),但不确定这是否是目前为止的最佳实践?
解决方法
添加标识列’rowid'(int或bigint,具体取决于您的表大小),并在其上创建唯一的非聚集索引.
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)范围内,因此建议的标识列添加.如果您的数据集具有其他分布,则结果将会偏斜(即,某些行的选择频率会高于其他行).