mysql slq随机取_从SQLSERVER/MYSQL数据库中随机取一条或者N条记录

本文介绍了如何从SQLSERVER和MYSQL数据库中随机选取一条或N条记录,对比了使用ORDER BY NEWID()和JOIN子查询的方法,强调了在JOIN子查询中使用RAND()以提高效率。同时,提供了MYSQL的类似示例,展示如何优化随机取记录的SQL语句。
摘要由CSDN通过智能技术生成

从SQLSERVER/MYSQL数据库中随机取一条或者N条记录

很多人都知道使用rand()函数但是怎麽使用可能不是每个人都知道

建立测试表

USE [sss]

GO

CREATE TABLE RANDTEST(ID INT DEFAULT RAND()*100,NAME NVARCHAR(200) DEFAULT 'nihao')GO

CREATE INDEX IX_RANDTEST_ID ONRANDTEST(ID)GO

INSERT INTO RANDTEST DEFAULT VALUES

GO 2000

SELECT * FROM RANDTEST

第一种写法:大家会想到ORDER BY NEWID()

SET STATISTICS TIME ON

SET STATISTICS IO ON

SELECT TOP 50 [id] FROM [dbo].[RANDTEST]

GROUP BYIDORDER BY NEWID()SET STATISTICS TIME OFF

SET STATISTICS IO OFF

这种写法使用到索引扫描,而且每次select出来的结果都是一样的,都是50条记录

dc99346d31548e1033589cee05f0c33b.png

1eef3d0b0c5837a18894a52694450788.png

第二种写法:

SET STATISTICS TIME ON

SET STATISTICS IO ON

SELECT TOP 50 [t1].[ID] FROM [dbo].[RANDTEST] t1 INNER JOIN (SELECT RAND()*100 AS nid) t2 ON [t1].[ID]>[t2].[nid]

GROUP BY [t1].[ID]

SET STATISTICS TIME OFF

SET STATISTICS IO OFF

跟t2这个表做比较,而且每次能够达到随机取一条或者N条记录的效果

每次select出来的行数都是不一样的

f6e18c8a924b7bc8821f834a7c4915dc.png

9ac6afde4a516a893e871ee9bfa85f35.png

比较一下IO和时间

当两种写法select出来的结果条数都是50条的时候,时间和IO都是一样的,如果第二种写法select出来的记录条数不是50条

那么IO肯定比第一种写法要少

--第一种写法 select出来50条记录

SQL Server 执行时间:

CPU 时间= 0 毫秒,占用时间 = 0毫秒。

(50行受影响)

表'RANDTEST'。扫描计数 1,逻辑读取 5 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0次。

SQL Server 执行时间:

CPU 时间= 0 毫秒,占用时间 = 1毫秒。------------------------------------------------------------------------------

--第二种写法 select出来37条记录

SQL Server 执行时间:

CPU 时间= 0 毫秒,占用时间 = 0毫秒。

(27行受影响)

表'RANDTEST'。扫描计数 1,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0次。

SQL Server 执行时间:

CPU 时间= 0 毫秒,占用时间 = 1 毫秒。

总结

如果第一种写法写成下面的样子,那么每次select出来的结果都是一样的,而且不会进行排序,在执行计划里面你看不到排序这个运算符

因为非聚集索引是排好序的,扫描非聚集索引只会得到排好序的结果

SELECT TOP 50 [id] FROM [dbo].[RANDTEST]

GROUP BYIDORDER BY RAND()*100

1fdba5102fe49f1e35dbd7a0fd912ab1.png

6d5a10099c161b367368d93ceda5d089.png

综上,想从SQLSERVER数据库中随机取一条或者N条记录时,最好把RAND()生成随机数放在JOIN子查询中以提高效率。

SELECT TOP n [id] FROM table

GROUP BYIDORDER BY NEWID()

改造成下面这个:

SELECT TOP n [t1].[ID] FROM table t1 JOIN (SELECT RAND()*100 AS nid) t2 ON [t1].[ID]>[t2].[nid]

GROUP BY [t1].[ID]

就可以享受在SQL中直接取得随机数了,不用再在程序中构造一串随机数去检索了。

MYSQL也是同样的原理

CREATE TABLE`t_innodb_random` (

`id`INT(10) UNSIGNED NOT NULL,

`user` VARCHAR(64) NOT NULL DEFAULT '',KEY`idx_id` (`id`)

) ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('1','lily');INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('3','tom');INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('5','fancy');INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('6','cici');INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('9','syan');SELECT * FROMt_innodb_random;SELECT id FROM t_innodb_random ORDER BY RAND() LIMIT 5;--改造成下面这个:

SELECT id FROM t_innodb_random t1 INNER JOIN (SELECT RAND()*10 AS nid) t2 ON t1.id > t2.nid LIMIT 5;

36e7213750a4f6c6df601caff61517e6.png

---------------------------------------------------------------------------------------------

7ca523bbeafc135afcba0d1b3595f7cf.png

如有不对的地方,欢迎大家拍砖o(∩_∩)o

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值