如何加快 SQL 服务器中的随机选择

How to speedUp Random selecting in SQL Server

我有一个 table 用于 phone 个数字,如下所示:

ID          PhoneNumber          Enabled GrupID CountryID
----------- -------------------- ------- ------ -----------
10444       ***001000999         1       NULL   1
10445       ***001000998         1       NULL   1
10446       ***001000994         1       NULL   1
10447       ***001000990         1       NULL   1
10448       ***001000989         1       NULL   1

这个 table 有 68992507 行。

我想从中 select 一些随机的 phone 号码。

我可以通过这个存储过程得到我的随机数查询:

这里我 select 随机数,插入到 @table 然后更新 selected 数字。

CREATE proc [dbo].[Mysp_GetRandom]
    @countryid int,
    @count int
as
    declare @tbl table([ID] [int] , 
                       [PhoneNumber] [nchar](20) NOT NULL,
                       [Enabled] [bit] NULL,
                       [GrupID] [tinyint] NULL,
                       [CountryID] [int] NULL)

    INSERT INTO @tbl
        SELECT TOP (@count) *
        FROM tblPhoneNumber
        WHERE CountryID = @countryid 
          AND GrupID is null
        ORDER BY binary_checksum(ID * rand())

    UPDATE tblPhoneNumber 
    SET GrupID = 1 
    WHERE ID IN (SELECT ID FROM @tbl)

    SELECT * FROM @tbl

问题是查询到运行需要很长时间。例如,此查询需要 12:30 分钟 ...

DECLARE @return_value int

EXEC @return_value = [dbo].[Mysp_GetRandom]
            @countryid = 14, @count = 3

SELECT 'Return Value' = @return_value

我有一个索引 table :

CREATE NONCLUSTERED INDEX [NonClusteredIndex-20150415-172433] 
ON [dbo].[tblPhoneNumber] ([CountryID] ASC)
         WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
               SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
               ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

执行计划如下:

谢谢...

看看你的查询计划,第一个 INSERT 语句几乎占了 100% 的时间,其中 70% 是排序。由于您已经在使用 BINARY_CHECKSUM,因此您无能为力。可能是 table 以足够随机的方式填充,以便从随机偏移量开始获取连续的行,如下所示:

SELECT ID FROM tblPhoneNumber WHERE CountryID = @countryid 
      AND GrupID is null ORDER BY ID OFFSET CONVERT(int, 
      rand()*(select count(*) from  tblPhoneNumber)-@count-1) 
      ROWS FETCH NEXT @count ROWS ONLY

将 grupID 添加到索引键列并在 NC 索引 NonClusteredIndex-20150415-172433 的 include 子句中添加其他必需的列。

执行计划已经为您提供了添加缺失索引的相同提示。

P.S如果对您有帮助,请设为答案。

您应该按条款替换订单。

您可以创建相当随机的 ID:

declare @count int = 100
; with ids(id, hex) as (
    Select 1, convert(bigint, convert(varbinary, '0x'+right(newid(), 6), 1 )) 
    Union all
    Select id+1, convert(bigint, convert(varbinary, '0x'+right(newid(), 6), 1 )) 
    From ids 
    Where id+1 <= @count 
)
Select * from ids
Option (MAXRECURSION 0)

然后您可以使用您的 table ID 加入 table。

您应该检查您的索引(其他人提到的)并在 phone Id 上添加索引。