MSSQL在大数据中随机选择

MSSQL在大数据中随机选择,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个超过一百万条记录的表,我想从这个表中选择随机行,但不是在所有记录中——只从匹配特定条件的结果中选择随机行 性能非常重要,所以我不能使用按NEWID排序然后选择第一项 表结构如下所示: ID BIGINT Title NVARCHAR(100) Level INT Point INT 现在,我编写了一个查询,如: with tmp_one as ( SELECT R.Id as RID

我有一个超过一百万条记录的表,我想从这个表中选择随机行,但不是在所有记录中——只从匹配特定条件的结果中选择随机行

性能非常重要,所以我不能使用按NEWID排序然后选择第一项

表结构如下所示:

 ID    BIGINT
 Title NVARCHAR(100)
 Level INT
 Point INT
现在,我编写了一个查询,如:

with 
    tmp_one as
    (
        SELECT
                R.Id as RID 
                FROM    [User] as U
                            Inner Join
                        [Item] as R
                            On  R.UserId = U.Id

                WHERE       ([R].[Level] BETWEEN @MinLevel AND @MaxLevel) 
                        AND ((ABS((BINARY_CHECKSUM(NEWID(),R.Id,NEWID())))% 10000)/100 ) > @RangeOne
    ),
    tmp_two as
    (
        Select  tmp_one.RID as RID
            From    tmp_one
            Where   ((ABS((BINARY_CHECKSUM(NEWID(),RID,NEWID())))% 10000)/100 ) > @RangeTwo
    ),
    tmp_three as
    (
        Select  RID as RID 
            From    tmp_two
            Where   ((ABS((BINARY_CHECKSUM(NEWID(),NEWID())))% 10000)/100 ) < @RangeThree
    )
    Select  top 10 RID
        From    tmp_three
我试图随机选择10个项目,然后选择其中一个,但我有一个惊人的问题

有时输出是按项目级别排序的!我不想要它,它不是随机的。我真的不知道结果是如何按级别排序的


请建议一些解决方案,帮助我选择高性能的随机记录,并在高迭代范围内选择不重复的随机记录。

尝试类似的方法。它将随机从您的表中抓取10行

这是伪代码,因此可能需要修复一些列名以匹配实际表

DECLARE @Random int
DECLARE @Result table
(ID BIGINT,
Title varchar(100),
Level int,
Point int)

declare @TotalRows int
set @TotalRows = (select COUNT(*) From [User] U inner join [Item] R on R.UserID = U.ID)

while (select COUNT(*) from @Result)<10
begin
set @Random = (select floor(RAND() * @TotalRows+1))

insert into @Result
select T1.ID, T1.Title, T1.Level, T1.Point from
(select top (@Random) * From [User] U inner join [Item] R on R.UserID = U.ID) T1
left outer join (select top (@Random) * From [User] U inner join [Item] R on R.UserID = U.ID) T2 on T2.ID = T1.ID
where T2.ID is null


end

select * from @Result
基于MSDN,而不是您避免的:

select top 10 * from TableName order by newid()
它表明:

select top 10 * from TableName where (abs(cast((binary_checksum(*) * rand()) as int)) % 100) < 10

它的逻辑读数小得多,性能好得多。

您拥有TOP,而无需订购。所以你是在告诉SQL Server我不在乎订单!因此,SQL Server将以其认为最有效的顺序将数据返回给您。好的,我如何防止这种有效的顺序,并告诉您只使用默认顺序而不更改它?插入顺序以及为什么在常规选择中不会发生这种情况,并选择在插入顺序中显示数据?请单击此处并阅读3:请阅读相关问题
select top 10 * from TableName where (abs(cast((binary_checksum(*) * rand()) as int)) % 100) < 10