如何在SQL Server中快速进行随机选择

时间:2015-08-13 06:55:36

标签: sql-server random ssms

我有一张电话号码表,如下:

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

此表有68992507行。

我想从中选择一些随机电话号码。

我可以通过此存储过程获取随机数查询:

这里我选择随机数,插入@table然后更新所选数字。

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

我在这张桌子上有一个ndex:

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

执行计划如下:

enter image description here

谢谢...

4 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我认为主要问题是order by子句。 查看这篇文章:

https://msdn.microsoft.com/en-us/library/cc441928.aspx

答案 2 :(得分:0)

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

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

P.S如果有帮助,请将其标记为答案。

答案 3 :(得分:0)

您应该替换您的订单条款。

您可以创建相当随机的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)

然后,您可以将其与表格一起加入表格。

您应该检查您的索引(由他人提及)并在手机ID上添加索引。