从SQLSERVER/MYSQL数据库中随机取一条或者N条记录
从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 ON RANDTEST(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 BY ID
ORDER BY NEWID()
SET STATISTICS TIME OFF
SET STATISTICS IO OFF
这种写法使用到索引扫描,而且每次select出来的结果都是一样的,都是50条记录


第二种写法:
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出来的行数都是不一样的


比较一下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 BY ID
ORDER BY RAND()*100


综上,想从SQLSERVER数据库中随机取一条或者N条记录时,最好把RAND()生成随机数放在JOIN子查询中以提高效率。
SELECT TOP n [id] FROM table
GROUP BY ID
ORDER 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('','lily');
INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('','tom');
INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('','fancy');
INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('','cici');
INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('','syan'); SELECT * FROM t_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;

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

如有不对的地方,欢迎大家拍砖o(∩_∩)o
从SQLSERVER/MYSQL数据库中随机取一条或者N条记录的更多相关文章
- laravel如何从mysql数据库中随机抽取n条数据
laravel如何从mysql数据库中随机抽取n条数据 一.总结 一句话总结: inRandomOrder():$userQuestions=UserQuestion::where($map)-> ...
- SQL 从数据库中随机取n条数据
用NEWID()方法. * ,NEWID() AS random from [toblename] order by random 其中的1可以换成其他任意整数,表示取的数据条数
- jsp如何判断mysql数据库中是否已经存在添加的某条记录的方法
String query="select * from hdxcy_info where XcyName='"+XcyName+"'"; String sqlS ...
- mysql管理 ------查看 MySQL 数据库中每个表占用的空间大小
如果想知道MySQL数据库中每个表占用的空间.表记录的行数的话,可以打开MySQL的 information_schema 数据库.在该库中有一个 TABLES 表,这个表主要字段分别是: TABLE ...
- [MySQL]MySQL数据库中如何查询分组后每组中的最后一条记录?
原文地址:https://codedefault.com/s/how-can-i-retrieve-the-last-record-in-each-group-mysql 问题描述 比如,在MySQL ...
- MySQL数据库中,将一个字段的值分割成多条数据显示
本文主要记录如何在MySQL数据库中,将一个字符串分割成多条数据显示. 外键有时是以字符串的形式存储,例如 12,13,14 这种,如果以这种形式存储,则不能直接与其他表关联查询,此时就需要将该字段的 ...
- 如何从mysql数据库中取到随机的记录
如何从mysql数据库中取到随机的记录 一.总结 一句话总结:用随机函数newID(),select top N * from table_name order by newid() ----N是一个 ...
- Python爬取招聘信息,并且存储到MySQL数据库中
前面一篇文章主要讲述,如何通过Python爬取招聘信息,且爬取的日期为前一天的,同时将爬取的内容保存到数据库中:这篇文章主要讲述如何将python文件压缩成exe可执行文件,供后面的操作. 这系列文章 ...
- node 爬虫 --- 将爬取到的数据,保存到 mysql 数据库中
步骤一:安装必要模块 (1)cheerio模块 ,一个类似jQuery的选择器模块,分析HTML利器. (2)request模块,让http请求变的更加简单 (3)mysql模块,node连接mysq ...
随机推荐
- angular run()运行块
和配置块不同,运行块在注入器创建之后被执行,它是所有AngularJS应用中第一个被执行的方法. 运行块是AngularJS中与main方法最接近的概念.运行块中的代码块通常很难进行单元测试,它是和应 ...
- js图片变换
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- MySQL的表的优化和列类型的选择
列选择原则: 1:字段类型优先级 整型 > date,time > enum,char>varchar > blob 列的特点分析: 整型: 定长,没有国家/地区之分,没有 ...
- CSS3常用选择器(二)
本文继续介绍css3新增的选择器. 1.选择器 first-child.last-child.nth-child 和 nth-last-child 利用这几个选择器能够针对一个父元素中的第一个子元素. ...
- Java NIO教程 文件系统
在NIO.2的文件系统中,Path是一切操作的基础.Path准确来说,代表着文件系统中的位置.可以代表一个目录(也就是通常所说的文件夹),也可以代表一个文件. 在新文件系统中,还有一个不得不说的就是F ...
- PHP的OB缓存(输出缓存)
使用PHP自带的缓存机制 原则:如果ob缓存打开,则echo的数据首先放在ob缓存.如果是header信息,直接放在程序缓存.当页面执行到最后,会把ob缓存的数据放到程序缓存,然后依次返回给浏览器. ...
- 《CSS3秘籍》(第三版)-读书笔记(2)
第6章 文本格式化 1. 使用字体 字体font-family: 通用的字体样式: serif字体最适用于冗长的文字信息.这种字体使字母主笔画的结尾处会有一些细小的“足”. sans-serif字体 ...
- 5.HotSpot的算法实现
1.枚举根节点 在可达性分析中,可以作为GC Roots的节点有很多,但是现在很多应用仅仅方法区就有上百MB,如果逐个检查的话,效率就会变得不可接受. 而且,可达性分析必须在一个一致性的快照中进行-即 ...
- URLEncoder编码
客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文. 而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址, 将网址中的非ASCII码内容转换成可以 ...
- 小甲鱼python视频第七讲(课后习题)
1.assert的作用. assert用来判断语句的真假,如果为假的话将触发AssertionError错误. 如果为真则继续执行. 2.变量互换(注意顺序) 3.成员资格运算符(in) 4.分数的划 ...