从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条记录的更多相关文章

  1. laravel如何从mysql数据库中随机抽取n条数据

    laravel如何从mysql数据库中随机抽取n条数据 一.总结 一句话总结: inRandomOrder():$userQuestions=UserQuestion::where($map)-> ...

  2. SQL 从数据库中随机取n条数据

    用NEWID()方法. * ,NEWID() AS random from [toblename] order by random 其中的1可以换成其他任意整数,表示取的数据条数

  3. jsp如何判断mysql数据库中是否已经存在添加的某条记录的方法

    String query="select * from hdxcy_info where XcyName='"+XcyName+"'"; String sqlS ...

  4. mysql管理 ------查看 MySQL 数据库中每个表占用的空间大小

    如果想知道MySQL数据库中每个表占用的空间.表记录的行数的话,可以打开MySQL的 information_schema 数据库.在该库中有一个 TABLES 表,这个表主要字段分别是: TABLE ...

  5. [MySQL]MySQL数据库中如何查询分组后每组中的最后一条记录?

    原文地址:https://codedefault.com/s/how-can-i-retrieve-the-last-record-in-each-group-mysql 问题描述 比如,在MySQL ...

  6. MySQL数据库中,将一个字段的值分割成多条数据显示

    本文主要记录如何在MySQL数据库中,将一个字符串分割成多条数据显示. 外键有时是以字符串的形式存储,例如 12,13,14 这种,如果以这种形式存储,则不能直接与其他表关联查询,此时就需要将该字段的 ...

  7. 如何从mysql数据库中取到随机的记录

    如何从mysql数据库中取到随机的记录 一.总结 一句话总结:用随机函数newID(),select top N * from table_name order by newid() ----N是一个 ...

  8. Python爬取招聘信息,并且存储到MySQL数据库中

    前面一篇文章主要讲述,如何通过Python爬取招聘信息,且爬取的日期为前一天的,同时将爬取的内容保存到数据库中:这篇文章主要讲述如何将python文件压缩成exe可执行文件,供后面的操作. 这系列文章 ...

  9. node 爬虫 --- 将爬取到的数据,保存到 mysql 数据库中

    步骤一:安装必要模块 (1)cheerio模块 ,一个类似jQuery的选择器模块,分析HTML利器. (2)request模块,让http请求变的更加简单 (3)mysql模块,node连接mysq ...

随机推荐

  1. IMS Global Learning Tools Interoperability™ Implementation Guide

    Final Version 1.1 Date Issued:            13 March 2012 Latest version:         http://www.imsglobal ...

  2. Provisional headers are shown,本地测试成功,服务器运行却失败

    基于MVC的项目 具体情况是一个页面在访问的时候进不了首页,但详细页面却可以进去 下面说说解决方法和思路,以便找出问题所在 第一:把服务器代码下载到本地运行,代码是否出错,出错了,问题找到了,没出错接 ...

  3. UVa 414 - Machined Surfaces

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=94&page=s ...

  4. Linux内核分析第二周学习总结:操作系统是如何工作的?

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 ...

  5. Linux课程实践一:Linux基础实践(基础操作)

    一.软件源维护 1. 基本操作 (1)查看源列表 sudo vim /etc/apt/sources.list deb:二进制软件安装包 deb-src:源码包 (2)备份软件源列表 sudo cp ...

  6. sendEmail的使用

    坑!坑!坑!今天又弄了一天如何发送邮件,首先用sendmail,postfix.....等,都试过了,各种报错,然后就从早上弄到现在,在群里问问题的时候,一位好心的大哥说了他用的是sendEmail, ...

  7. Html模板

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5.0 Transitional//EN"> <!-- saved from ur ...

  8. java 查询 mongodb 中的objectid

    网上找了很久查询objectid的方法都是错的,用mongovue能查询出来,但就是用java不知道怎么查询 1.mongovue里的查询方式: {"_id" : ObjectId ...

  9. VS2010安装异常中断后无法安装的解决方法(安装时发生严重错误)

    最近,因为公司开发的需要,对开发环境进行全面的升级,在这其中也遇到了不少问题,在之后将陆续整理出来,以便以后查看. 之前开发环境:ArcGIS9.3,ArcEngine9.3,Oracle10g,Ar ...

  10. DB2不记录事务日志

    1. DB2大数据处理不记录事务日志步骤:  建表需要添加属性“NOT LOGGED INITIALLY”  在大批量更改操作的同一个事务开始时执行:“ALTER TABLE tabname ACTI ...